class ThreadSafe::MriCacheBackend

Constants

WRITE_LOCK

We can get away with a single global write lock (instead of a per-instance one) because of the GVL/green threads.

The previous implementation used `Thread.critical` on 1.8 MRI to implement the 4 composed atomic operations (`put_if_absent`, `replace_pair`, `replace_if_exists`, `delete_pair`) this however doesn't work for `compute_if_absent` because on 1.8 the Mutex class is itself implemented via `Thread.critical` and a call to `Mutex#lock` does not restore the previous `Thread.critical` value (thus any synchronisation clears the `Thread.critical` flag and we loose control). This poses a problem as the provided block might use synchronisation on its own.

NOTE: a neat idea of writing a c-ext to manually perform atomic put_if_absent, while relying on Ruby not releasing a GVL while calling a c-ext will not work because of the potentially Ruby implemented `#hash` and `#eql?` key methods.

Public Instance Methods

[]=(key, value) click to toggle source
Calls superclass method
# File lib/thread_safe/mri_cache_backend.rb, line 21
def []=(key, value)
  WRITE_LOCK.synchronize { super }
end
clear() click to toggle source
Calls superclass method
# File lib/thread_safe/mri_cache_backend.rb, line 65
def clear
  WRITE_LOCK.synchronize { super }
end
compute(key) click to toggle source
Calls superclass method
# File lib/thread_safe/mri_cache_backend.rb, line 37
def compute(key)
  WRITE_LOCK.synchronize { super }
end
compute_if_absent(key) click to toggle source
Calls superclass method
# File lib/thread_safe/mri_cache_backend.rb, line 25
def compute_if_absent(key)
  if stored_value = _get(key) # fast non-blocking path for the most likely case
    stored_value
  else
    WRITE_LOCK.synchronize { super }
  end
end
compute_if_present(key) click to toggle source
Calls superclass method
# File lib/thread_safe/mri_cache_backend.rb, line 33
def compute_if_present(key)
  WRITE_LOCK.synchronize { super }
end
delete(key) click to toggle source
Calls superclass method
# File lib/thread_safe/mri_cache_backend.rb, line 57
def delete(key)
  WRITE_LOCK.synchronize { super }
end
delete_pair(key, value) click to toggle source
Calls superclass method
# File lib/thread_safe/mri_cache_backend.rb, line 61
def delete_pair(key, value)
  WRITE_LOCK.synchronize { super }
end
get_and_set(key, value) click to toggle source
Calls superclass method
# File lib/thread_safe/mri_cache_backend.rb, line 53
def get_and_set(key, value)
  WRITE_LOCK.synchronize { super }
end
merge_pair(key, value) click to toggle source
Calls superclass method
# File lib/thread_safe/mri_cache_backend.rb, line 41
def merge_pair(key, value)
  WRITE_LOCK.synchronize { super }
end
replace_if_exists(key, new_value) click to toggle source
Calls superclass method
# File lib/thread_safe/mri_cache_backend.rb, line 49
def replace_if_exists(key, new_value)
  WRITE_LOCK.synchronize { super }
end
replace_pair(key, old_value, new_value) click to toggle source
Calls superclass method
# File lib/thread_safe/mri_cache_backend.rb, line 45
def replace_pair(key, old_value, new_value)
  WRITE_LOCK.synchronize { super }
end