Permalink
Browse files

split the pool class on its own module

  • Loading branch information...
1 parent a40a49d commit 2002eca29d9e2fca2a709171e4f0f7fd9be88225 @tarekziade tarekziade committed Aug 1, 2012
Showing with 73 additions and 68 deletions.
  1. +5 −68 memcachepool/cache.py
  2. +68 −0 memcachepool/pool.py
View
@@ -1,74 +1,11 @@
-import time
-import Queue
import sys
-import contextlib
+try:
+ import cPickle as pickle
+except ImportError:
+ import pickle
from django.core.cache.backends.memcached import MemcachedCache
-
-# Sentinel used to mark an empty slot in the MCClientPool queue.
-# Using sys.maxint as the timestamp ensures that empty slots will always
-# sort *after* live connection objects in the queue.
-EMPTY_SLOT = (sys.maxint, None)
-
-
-class ClientPool(object):
-
- def __init__(self, factory, maxsize=None, timeout=60):
- self.factory = factory
- self.maxsize = maxsize
- self.timeout = timeout
- self.clients = Queue.PriorityQueue(maxsize)
- # If there is a maxsize, prime the queue with empty slots.
- if maxsize is not None:
- for _ in xrange(maxsize):
- self.clients.put(EMPTY_SLOT)
-
- @contextlib.contextmanager
- def reserve(self):
- """Context-manager to obtain a Client object from the pool."""
- ts, client = self._checkout_connection()
- try:
- yield client
- finally:
- self._checkin_connection(ts, client)
-
- def _checkout_connection(self):
- # If there's no maxsize, no need to block waiting for a connection.
- blocking = self.maxsize is not None
- # Loop until we get a non-stale connection, or we create a new one.
- while True:
- try:
- ts, client = self.clients.get(blocking)
- except Queue.Empty:
- # No maxsize and no free connections, create a new one.
- # XXX TODO: we should be using a monotonic clock here.
- now = int(time.time())
- return now, self.factory()
- else:
- now = int(time.time())
- # If we got an empty slot placeholder, create a new connection.
- if client is None:
- return now, self.factory()
- # If the connection is not stale, go ahead and use it.
- if ts + self.timeout > now:
- return ts, client
- # Otherwise, the connection is stale.
- # Close it, push an empty slot onto the queue, and retry.
- client.disconnect_all()
- self.clients.put(EMPTY_SLOT)
- continue
-
- def _checkin_connection(self, ts, client):
- """Return a connection to the pool."""
- # If the connection is now stale, don't return it to the pool.
- # Push an empty slot instead so that it will be refreshed when needed.
- now = int(time.time())
- if ts + self.timeout > now:
- self.clients.put((ts, client))
- else:
- if self.maxsize is not None:
- self.clients.put(EMPTY_SLOT)
-
+from memcachepool.pool import ClientPool
# XXX not sure if keeping the base BaseMemcachedCache class has anymore value
class UMemcacheCache(MemcachedCache):
View
@@ -0,0 +1,68 @@
+import Queue
+import time
+import contextlib
+import sys
+
+# Sentinel used to mark an empty slot in the MCClientPool queue.
+# Using sys.maxint as the timestamp ensures that empty slots will always
+# sort *after* live connection objects in the queue.
+EMPTY_SLOT = (sys.maxint, None)
+
+
+class ClientPool(object):
+
+ def __init__(self, factory, maxsize=None, timeout=60):
+ self.factory = factory
+ self.maxsize = maxsize
+ self.timeout = timeout
+ self.clients = Queue.PriorityQueue(maxsize)
+ # If there is a maxsize, prime the queue with empty slots.
+ if maxsize is not None:
+ for _ in xrange(maxsize):
+ self.clients.put(EMPTY_SLOT)
+
+ @contextlib.contextmanager
+ def reserve(self):
+ """Context-manager to obtain a Client object from the pool."""
+ ts, client = self._checkout_connection()
+ try:
+ yield client
+ finally:
+ self._checkin_connection(ts, client)
+
+ def _checkout_connection(self):
+ # If there's no maxsize, no need to block waiting for a connection.
+ blocking = self.maxsize is not None
+ # Loop until we get a non-stale connection, or we create a new one.
+ while True:
+ try:
+ ts, client = self.clients.get(blocking)
+ except Queue.Empty:
+ # No maxsize and no free connections, create a new one.
+ # XXX TODO: we should be using a monotonic clock here.
+ now = int(time.time())
+ return now, self.factory()
+ else:
+ now = int(time.time())
+ # If we got an empty slot placeholder, create a new connection.
+ if client is None:
+ return now, self.factory()
+ # If the connection is not stale, go ahead and use it.
+ if ts + self.timeout > now:
+ return ts, client
+ # Otherwise, the connection is stale.
+ # Close it, push an empty slot onto the queue, and retry.
+ client.disconnect_all()
+ self.clients.put(EMPTY_SLOT)
+ continue
+
+ def _checkin_connection(self, ts, client):
+ """Return a connection to the pool."""
+ # If the connection is now stale, don't return it to the pool.
+ # Push an empty slot instead so that it will be refreshed when needed.
+ now = int(time.time())
+ if ts + self.timeout > now:
+ self.clients.put((ts, client))
+ else:
+ if self.maxsize is not None:
+ self.clients.put(EMPTY_SLOT)

0 comments on commit 2002eca

Please sign in to comment.