Class: SynCache::RemoteCache
- Inherits:
-
Object
- Object
- SynCache::RemoteCache
- Defined in:
- lib/syncache/remote.rb
Overview
Connects to a remote SynCache instance over DRb at the provided URI and replaces the remote fetch_or_add method with a slightly less bullet-proof version that invokes the supplied block locally (instead of sending it over DRb to the cache and then back to a different local thread via a local DRb service).
If another RemoteCache client is already working on the same key, this client will wait, using randomly increasing intervals. When a configured timeout runs out (counting from the time the other client has put a placeholder in the cache), the client will give up, discard the other client’s placeholder and start working on the key itself.
Mixing access to the same cache entries from direct and RemoteCache clients is not recommended.
Instance Method Summary collapse
- #fetch_or_add(key) ⇒ Object
-
#initialize(uri, timeout = REMOTE_TIMEOUT, first_delay = REMOTE_FIRST_DELAY) ⇒ RemoteCache
constructor
A new instance of RemoteCache.
- #method_missing(method, *args) ⇒ Object
Constructor Details
#initialize(uri, timeout = REMOTE_TIMEOUT, first_delay = REMOTE_FIRST_DELAY) ⇒ RemoteCache
Returns a new instance of RemoteCache.
49 50 51 52 53 |
# File 'lib/syncache/remote.rb', line 49 def initialize(uri, timeout=REMOTE_TIMEOUT, first_delay=REMOTE_FIRST_DELAY) @timeout = timeout @first_delay = first_delay @cache = DRbObject.new_with_uri(uri) end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method, *args) ⇒ Object
55 56 57 |
# File 'lib/syncache/remote.rb', line 55 def method_missing(method, *args) @cache.send(method, *args) end |
Instance Method Details
#fetch_or_add(key) ⇒ Object
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/syncache/remote.rb', line 59 def fetch_or_add(key) placeholder = Placeholder.new value = @cache.fetch_or_add(key) { placeholder } case value when placeholder # our placeholder value = @cache[key] = yield when Placeholder # someone else's placeholder delay = @first_delay while value.kind_of?(Placeholder) and Time.now < value. + @timeout sleep(delay) delay *= 1 + rand value = @cache[key] end if value.kind_of?(Placeholder) or value.nil? # the other client timed out or got flushed; # reset the placeholder ttl and do it ourselves @cache[key] = Placeholder.new value = @cache[key] = yield end end value end |