Boris
Boris

Reputation: 1136

Google App Engine. How to make synchronized actions using memcache or datastore?

My main goal is to be able to have some synchronized method that shouldn't be accessed by other threads until it is finished. If I had usual VM - I would mark this method as synchronized. But in GAE I have multiple instances. All posts that I read about this say that I should use memcache or datastore. But how exactly ?

Upvotes: 5

Views: 2629

Answers (2)

Alexey Smychagin
Alexey Smychagin

Reputation: 19

Actually I don't use that kind of synchronization a lot. Once I did. It seems to work pretty well. Here is an example

String syncKey = "Sync:" + req.getRequestURI();
boolean lockAcquired = false;
try {
  lockAcquired = acquireLock(syncKey, 5000L);
  if (!lockAcquired) {
    return;
  }
  // do something here

} finally {
  if (lockAcquired) {
    memcacheService.delete(syncKey);
  }
}


public boolean acquireLock(String syncKey, long maxwait) {
  long start = System.currentTimeMillis();
  while (true) {
    if (memcacheService.increment(syncKey, 1L, 0L) == 1L) {
      return true;
    }
    if (System.currentTimeMillis() - start > maxwait) {
      return false;
    }
    try {
      Thread.sleep(100L);
    } catch (InterruptedException e) {
    }
  }
}

Usually I use more simpler synchronization. It gives me opportunity to run some piece of code only once.

final long now = System.currentTimeMillis() / (60L * 1000L); // expire every minute
if (memcacheService.increment("VoteRemoveOldTask" + now, 1L, 1L) == 1L) {
  QueueFactory.getDefaultQueue().add(
      TaskOptions.Builder.withDefaults().url(VoteRemoveOldTask.URL));
}

Upvotes: 1

dragonx
dragonx

Reputation: 15143

Usually the answer is redesign the function so it doesn't need to be globally synchronized. Even if you manage to synchronize it, it's a single bottleneck.

You're probably best off to implement it on a backend; you can specify a single backend, and make your function call a request to the backend. You can also use memcache or the datastore as semaphore, but all of those are going to give you poor performance.

Upvotes: 6

Related Questions