I have a python web app that uses the pylibmc module to connect to a memcached server. If I test my app with requests once per second or slower, everything works fine. If I send more than one request per second, however, my app crashes and I see the following in my logs:
Assertion "ptr->query_id == query_id +1" failed for function "memcached_get_by_key" likely for "Programmer error, the query_id was not incremented.", at libmemcached/get.cc:107
Assertion "ptr->query_id == query_id +1" failed for function "memcached_get_by_key" likely for "Programmer error, the query_id was not incremented.", at libmemcached/get.cc:89
Any idea what's going wrong or how to fix it?
My code looks like this:
self.mc = pylibmc.Client(
servers=[os.environ.get(MEMCACHE_SERVER_VAR)],
username=os.environ.get(MEMCACHE_USER_VAR),
password=os.environ.get(MEMCACHE_PASS_VAR),
binary=True
)
#...
if (self.mc != None):
self.mc.set(key, stored_data)
#...
page = self.mc.get(key)
This is a threading issue. pylibmc clients are not thread-safe. You should convert your code to use a ThreadMappedPool object to ensure you keep a separate connection for each thread. Something like this:
mc = pylibmc.Client(
servers=[os.environ.get(MEMCACHE_SERVER_VAR)],
username=os.environ.get(MEMCACHE_USER_VAR),
password=os.environ.get(MEMCACHE_PASS_VAR),
binary=True
)
self.pool = pylibmc.ThreadMappedPool(mc)
#...
if (self.pool != None):
with self.pool.reserve() as mc:
mc.set(key, stored_data)
#...
if (self.pool != None):
with self.pool.reserve() as mc:
page = mc.get(key)
Make sure to call self.pool.relinquish()
when the thread is finished, possibly in the destructor!
(In my case this happened because I was using cherrypy as my web server, and cherrypy spawns 10 separate threads to serve requests by default.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With