Google App Engine How to perform synchronized actions using memcache or data warehouse?

My main goal is to have some kind of synchronized method that other threads should not access until it is complete. If I had a regular VM, I would mark this method as synchronized. But in GAE, I have several instances. All the posts I read about this say that I should use memcache or datastore. But how exactly?

+4
source share
2 answers

Usually the answer is a redesign of the function, so global synchronization is not required. Even if you manage to sync it, this is one bottleneck.

Perhaps your best bet is to implement it on the backend; you can specify one backend and force your function to call a request for the backend. You can also use memcache or data storage as a semaphore, but all of them will give you poor performance.

+6
source

In fact, I do not use such synchronization. As soon as I did it. It seems to work very 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) { } } } 

I usually use more simplified synchronization. This gives me the ability to run part of the 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)); } 
+1
source

All Articles