views:

355

answers:

4

Hi,

i need a locking in memcache. Since all operations are atomic that should be an easy task. My idea is to use a basic spin-lock mechanism. So every object that needs locking in memcache gets a lock object, which will be polled for access.

// pseudo code
// try to get a lock
int lock;
do
{
  lock = Memcache.increment("lock", 1);
}
while(lock != 1)

// ok we got the lock
// do something here

// and finally unlock
Memcache.put("lock", 0);

How does such a solution perform? Do you have a better idea how to lock a memcache object?

Best regards,

Friedrich Schick

+3  A: 

Be careful. You could potentially burn through a lot of your quota in that loop.

cope360
+2  A: 

Locking is generally a bad idea - and in your example, will result in a busy-wait loop that consumes huge amounts of quota.

What do you need locking for? Perhaps we can suggest a better alternative.

Nick Johnson
A: 

If you really do need a loop: don't busy-wait, but include a delay, possibly with exponential back-off:

int delay = 100;
do {
    lock = Memcache.increment("lock", 1);
    usleep(delay);
    delay = min(delay * 2, 100000);
}
while (!lock);
Wim
A: 

All operations on memcache are atomic, as you said. To echo others' responses, do not use a naive spin lock on the app engine. You'll use up your daily quota in about 20 minutes. Now, to your solution:

I've done something like this. I created a task queue with a bucket size of 1 and a exec rate of 1/10s (one task per 10 seconds). I used this queue for "spinning", except that it has the advantage of only checking once per 10 seconds. I'm not sure what your use case is, but even executing a task once per second is far better than just spinning in a loop. So you implement a task servlet that checks the status of this lock and, if free, does whatever you want it to do.

Travis J Webb