Object creation/locking issue

Evan Martin martine@danga.com
Wed, 18 Feb 2004 09:16:53 -0800


On Wed, Feb 18, 2004 at 08:40:40AM -0600, Keeble, Tom wrote:
> Here is a scenario -- taking usage out of the pure web-interface
> implementation: 
> 
> Supposing I wish to cache objects that are computationally expensive to
> generate, ie to the order of a few seconds up to 15 minutes.  I can have
> unique keys, put them in namespaces, and otherwise identify them, but I
> really do not want to be generating them in parallel, as that chews up
> resources.
> 
> So, if a process discovers that the object is not in the cache, it needs
> to 'lock' that key before going off to generate the object, so that any
> other process looking up that object are blocked until it has been put
> in to the cache.  Clearly, the block would have to be dropped if that
> other process dies (or unlocks the key) without generating the object.

When process A locks key K, I assume process B wants to be able to see
that A has locked it and have it choose some other process, right?
(Otherwise, you may as well have both A and B compute it because they're
both going to be waiting that long anyway.)

So just add the key "K_lock" to "A", and have all your processes check
that before calculating K.  (More specifically:  "add" will not replace
an existing key, so to prevent races each process should add the key,
then immediately get it to verify they were the one who managed to grab
the lock.)  If A decides to give up, it clears K_lock without setting K. 

Detecting when another process dies is more complicated, and I'm not
sure how any system could help you.  :)
(I guess if there was some way to bind K_lock's lifetime to the lifetime
of the A's TCP connection?  But memcache definitely doesn't do that.)

Just thinking aloud:
  - One option would be to set K_lock to a timestamp and have B decide A
    has died after some amount of time.
  - Another would be to set K_lock to "A", and have A periodically
    update "A_alive" to the current time.  Whenever B pokes K_lock, it
    follows it to A_alive to make sure that A is still processing.

-- 
Evan Martin
martine@danga.com
http://neugierig.org