Class: ThreadSafe::MriCacheBackend
- Inherits:
-
NonConcurrentCacheBackend
show all
- Defined in:
- lib/thread_safe/mri_cache_backend.rb
Constant Summary
- 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
- (Object) []=(key, value)
21
22
23
|
# File 'lib/thread_safe/mri_cache_backend.rb', line 21
def []=(key, value)
WRITE_LOCK.synchronize { super }
end
|
- (Object) clear
65
66
67
|
# File 'lib/thread_safe/mri_cache_backend.rb', line 65
def clear
WRITE_LOCK.synchronize { super }
end
|
- (Object) compute(key)
37
38
39
|
# File 'lib/thread_safe/mri_cache_backend.rb', line 37
def compute(key)
WRITE_LOCK.synchronize { super }
end
|
- (Object) compute_if_absent(key)
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
|
- (Object) compute_if_present(key)
33
34
35
|
# File 'lib/thread_safe/mri_cache_backend.rb', line 33
def compute_if_present(key)
WRITE_LOCK.synchronize { super }
end
|
- (Object) delete(key)
57
58
59
|
# File 'lib/thread_safe/mri_cache_backend.rb', line 57
def delete(key)
WRITE_LOCK.synchronize { super }
end
|
- (Object) delete_pair(key, value)
61
62
63
|
# File 'lib/thread_safe/mri_cache_backend.rb', line 61
def delete_pair(key, value)
WRITE_LOCK.synchronize { super }
end
|
- (Object) get_and_set(key, value)
53
54
55
|
# File 'lib/thread_safe/mri_cache_backend.rb', line 53
def get_and_set(key, value)
WRITE_LOCK.synchronize { super }
end
|
- (Object) merge_pair(key, value)
41
42
43
|
# File 'lib/thread_safe/mri_cache_backend.rb', line 41
def merge_pair(key, value)
WRITE_LOCK.synchronize { super }
end
|
- (Object) replace_if_exists(key, new_value)
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
|
- (Object) replace_pair(key, old_value, new_value)
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
|