Saturday, March 21, 2009

Memcache-based circular buffer for Google App Engine

The problem: AppEngine's datastore is slow and uses a lot of cpu.

One solution: store non mission-critical data in memcache only. Your app might not have any data that you can be ok with losing, but there are a lot of good examples for games: chat messages, console messages, status updates... it's ok if these things get lost for some reason and we aren't interested in keeping them around for a long time anyway.

Here is some code to get you started with a circular buffer. Basically we have 10 memcache keys for data and one key that is used as an index (iter). The last ten items stored are available in order from most recent to least recent, and if a new item is added it replaces the oldest item while still being returned at the front of the list thanks to the sorting.

If you don't have other things you don't mind being kicked out of cache you can modify this code to just keep increasing the iter value instead of performing mod 10 such that old keys are not overwritten. This should save you some cpu time. Eventually the old items will be kicked out of cache automatically.

Anyway, here is the code:

from google.appengine.api import memcache

def addToBuffer(bufferData):
  loc = memcache.incr("myBufferIter")
  if loc == None:
    memcache.set("theIter", "0")
    loc = 0
  memcache.set(key="myBufferData%d" % (loc % 10), value=text)

def getBufferData():
  keys = []
  try:
    iter = int(memcache.get(key="myBufferIter"))
    for i in range (0, 10):
      keys.append('%d' % i)
    results = memcache.get_multi(keys, "myBufferData")

    # You can omit this part if you don't care about the order of the data
    sortedResults = []
    for i in range (iter%10, 0, -1) + range(9, iter%10, -1):
      sortedResults.append(results[str(i)])
    return sortedResults
  except:
    return None

Be the first to reply!

Post a Comment

By submitting a comment you assert that it is your own original work and agree to grant a non-exclusive licence to Brandon Thomson to display it on log.bthomson.com.