Feature request: lock a key

Per Wigren tuxie at dekadance.se
Fri Sep 10 10:30:54 PDT 2004

That approach would add a lot of unwanted complexity to my PHP code. I 
prefer to handle things at the lowest level possible. :)

I (want to) use a cached array for two things:

1: Keep track of which cached HTML-pages belong to which 
objects/variables. I'm working on a community website and I want to keep 
the generated HTML cached until some variable the HTML depends on has 
changed. For example the generated HTML of a user's guestbook should be 
cached until somebody post a new entry in her guestbook. The guestbook 
will look different depending on which user is looking at it 
(userconfigurable timezones, and the user herself get additional options 
like "delete" and "reply") so I want to add the cache-key of the 
generated pages ("guestbook.$userid.$timezone.$is_owner") to a global 
array like "guestbook.$userid" so I can recursivly delete them on a new 

2: Tracking average page-generation-times for debugging/profiling 
without having to hit the database on every pageview.

In the HTML-example, if a cached HTML page get lost from memcache it's 
no big deal because it will be regenerated on the next view. But if a 
"keytracker" misses a page it won't be regenerated at all so the new 
message won't be seen. I will put a TTL on generated HTML so the 
"feature" will disappear in 1 or 2 hours, but it will be annoying anyway...

The reason I don't want to cache to disk is because I want my site to be 
simple to load-balance in the future when it's needed, without depending 
on a central NFS-server... I don't even use a session-handler, only two 
cookies (userid+authcode) and memcached. :)

If you have smarter solutions I'd love to hear them! :)

Per Wigren

Jamie McCarthy wrote:

>You could implement locking using any other mechanism that
>supports it of course:  flock() on a local filesystem,
>LOCK TABLE on a database table or something.  Or you can do this
>using memcached's incr and decr, which atomically increment a
>value you can use as a semaphore:
>sub get_lock {
>    my $val;
>    while (1) {
>        $val = $cache->incr("mykey");
>        return 1 if !defined($val); # means we're the first lock ever
>        return 1 if $val == 1; # means we got the lock
>        # $val must be > 1, so we didn't get the lock (yet)
>        $cache->decr("mykey"); # give up our claim
>        # might be nice here to bomb out w/error after n retries
>        Time::HiRes::sleep(rand()); # wait random time before retrying
>    }
>sub release_lock {
>    $cache->decr("mykey");
>To be robust about it, you'd probably want signal handlers that
>clean up any locks you're holding, else ^C'ing your program at the
>wrong time could keep every other program from using that resource.
>Maybe you could write an object that grabs the lock when it's
>created and gives it up in its DESTROY method, so you'd be less
>likely to goof up and call the wrong function once too often.
>Of course, if you wanted robustness, you wouldn't be using a
>storage mechanism that is specifically designed to handle some of
>its servers going down every so often and throwing some or all of
>its data away and starting over.  I hope you're using this for
>quickie projects and not my bank account :)

More information about the memcached mailing list