Class: ThreadSafe::MriCacheBackend
Constant Summary
collapse
- 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.
Mutex.new
Instance Method Summary
collapse
Instance Method Details
#[]=(key, value) ⇒ Object
21
22
23
|
# File 'lib/thread_safe/mri_cache_backend.rb', line 21
def []=(key, value)
WRITE_LOCK.synchronize { super }
end
|
#clear ⇒ Object
65
66
67
|
# File 'lib/thread_safe/mri_cache_backend.rb', line 65
def clear
WRITE_LOCK.synchronize { super }
end
|
#compute(key) ⇒ Object
37
38
39
|
# File 'lib/thread_safe/mri_cache_backend.rb', line 37
def compute(key)
WRITE_LOCK.synchronize { super }
end
|
#compute_if_absent(key) ⇒ Object
25
26
27
28
29
30
31
|
# File 'lib/thread_safe/mri_cache_backend.rb', line 25
def compute_if_absent(key)
if stored_value = _get(key) stored_value
else
WRITE_LOCK.synchronize { super }
end
end
|
#compute_if_present(key) ⇒ Object
33
34
35
|
# File 'lib/thread_safe/mri_cache_backend.rb', line 33
def compute_if_present(key)
WRITE_LOCK.synchronize { super }
end
|
#delete(key) ⇒ Object
57
58
59
|
# File 'lib/thread_safe/mri_cache_backend.rb', line 57
def delete(key)
WRITE_LOCK.synchronize { super }
end
|
#delete_pair(key, value) ⇒ Object
61
62
63
|
# 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) ⇒ Object
53
54
55
|
# 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) ⇒ Object
41
42
43
|
# 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) ⇒ Object
49
50
51
|
# 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) ⇒ Object
45
46
47
|
# File 'lib/thread_safe/mri_cache_backend.rb', line 45
def replace_pair(key, old_value, new_value)
WRITE_LOCK.synchronize { super }
end
|