Skip to content

Instantly share code, notes, and snippets.

@dound
Created May 5, 2010 20:45
Show Gist options
  • Save dound/391399 to your computer and use it in GitHub Desktop.
Save dound/391399 to your computer and use it in GitHub Desktop.
def incrementCounter(key, update_interval=10):
"""Increments a memcached counter.
Args:
key: The key of a datastore entity that contains the counter.
update_interval: Minimum interval between updates.
"""
lock_key = "counter_lock:%s" % (key,)
count_key = "counter_value:%s" % (key,)
if memcache.add(lock_key, None, time=update_interval):
# Time to update the DB
count = int(memcache.get(count_key) or 0) + 1
def tx():
entity = db.get(key)
entity.counter += count
entity.put()
deferred.defer(memcache.decr, count_key, delta=count, _transactional=True)
try:
db.run_in_transaction(tx)
except:
memcache.incr(count_key, initial_value=0)
else:
# Just update memcache
memcache.incr(count_key, initial_value=0)
@dound
Copy link
Author

dound commented May 5, 2010

The initial commit fe5edc is the original recipe by Nick Johnson: http://appengine-cookbook.appspot.com/recipe/high-concurrency-counters-without-sharding

@dound
Copy link
Author

dound commented May 5, 2010

Commit c3fc97 is the revised recipe by evlogimenos.

@dound
Copy link
Author

dound commented May 5, 2010

Commit 8b1063 is the revised recipe by me. It includes a doctest which can be run with nosegae.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment