diff options
author | Leif Johansson <leifj@sunet.se> | 2012-02-09 00:16:16 +0100 |
---|---|---|
committer | Leif Johansson <leifj@sunet.se> | 2012-02-09 00:16:16 +0100 |
commit | ad21e8e4e5ac8f9eb38830f3024e19fd9329e288 (patch) | |
tree | 4aa7d7c3a6cd66cae59708e5bba274ce1cdb1eba /src/meetingtools/ac | |
parent | 635d92fc5ded0faec71849554224608f0424fae2 (diff) |
* refactor api
* now depends on with statement
* object-pool using queues
Diffstat (limited to 'src/meetingtools/ac')
-rw-r--r-- | src/meetingtools/ac/__init__.py | 86 | ||||
-rw-r--r-- | src/meetingtools/ac/api.py | 17 |
2 files changed, 61 insertions, 42 deletions
diff --git a/src/meetingtools/ac/__init__.py b/src/meetingtools/ac/__init__.py index 2727d67..6523475 100644 --- a/src/meetingtools/ac/__init__.py +++ b/src/meetingtools/ac/__init__.py @@ -1,53 +1,57 @@ from meetingtools.ac.api import ACPClient import time from meetingtools.apps.cluster.models import acc_for_user +from django.core.cache import cache +from Queue import Queue +import logging +from django.contrib.auth.models import User -def ac_api_client_cache(request,acc=None): - if acc == None: - acc = acc_for_user(request.user) - tag = 'ac_api_client_%s' % acc.name - if not request.session.has_key(tag): - request.session[tag] = ACPClientWrapper(acc) - - return request.session[tag] - -def ac_api_client_nocache(request,acc=None): - if acc == None: - acc = acc_for_user(request.user) - return ACPClientWrapper(acc) - -def ac_api_client_direct(acc): - return ACPClientWrapper(acc) - -ac_api_client = ac_api_client_cache - -def ac_api(request,acc=None): - return ACPClient(acc.api_url,acc.user,acc.password) +_pools = {} MAXCALLS = 10 MAXIDLE = 10 -class ACPClientWrapper(object): +class ClientPool(object): - def __init__(self,acc): - self.acc = acc - self._delegate = None - self.ncalls = 0 - self.lastcall = time.time() - - def invalidate(self): - self._delegate = None - - def client_factory(self): + def __init__(self,acc,maxsize=0,increment=5): + self._q = Queue(maxsize) + self._acc = acc + self._increment = increment + + def allocate(self): now = time.time() - if self.ncalls > MAXCALLS or now - self.lastcall > MAXIDLE or not self._delegate: - self._delegate = ACPClient(self.acc.api_url,self.acc.user,self.acc.password) - self.ncalls = 0 - self.ncalls += 1 - self.lastcall = now - return self._delegate + api = None + while not api: + if self._q.empty(): + for i in range(1,self._increment): + logging.debug("adding instance %d" % i) + api = ACPClient(self._acc.api_url,self._acc.user,self._acc.password,cpool=self) + self._q.put_nowait(api) + + api = self._q.get() + if api and (api.age > MAXCALLS or now - api.lastused > MAXIDLE): + api = None + return api + +# with ac_api_client(acc) as api +# ... + +def ac_api_client(o): + acc = o + logging.debug("ac_api_client(%s)" % repr(o)) + if hasattr(o,'user') and isinstance(getattr(o,'user'),User): + acc = acc_for_user(getattr(o,'user')) + elif hasattr(o,'acc'): + acc = getattr(o,'acc') + + tag = 'ac_api_client_%d' % acc.id + pool = _pools.get(tag) + if pool is None: + pool = ClientPool(acc,maxsize=30) + _pools[tag] = pool - def __getattr__(self,name): - client = self.client_factory() - return getattr(client,name) + return pool.allocate() + + +
\ No newline at end of file diff --git a/src/meetingtools/ac/api.py b/src/meetingtools/ac/api.py index c17d500..4d5559f 100644 --- a/src/meetingtools/ac/api.py +++ b/src/meetingtools/ac/api.py @@ -10,6 +10,7 @@ import logging from pprint import pformat import os import tempfile +import time from lxml import etree from meetingtools.site_logging import logger import lxml @@ -67,15 +68,29 @@ def _getset(d,key,value=None): class ACPClient(): - def __init__(self,url,username=None,password=None,cache=True): + def __init__(self,url,username=None,password=None,cache=True,cpool=None): + self._cpool = cpool + self.age = 0 + self.createtime = time.time() + self.lastused = self.createtime self.url = url self.session = None if username and password: self.login(username,password) if cache: self._cache = {'login':{},'group':{}} + + def __exit__(self,type,value,traceback): + if self._cpool: + self._cpool._q.put_nowait(self) + + def __enter__(self): + return self + def request(self,method,p={},raise_error=False): + self.age += 1 + self.lastused = time.time() u = [] u.append("action=%s" % method) if self.session: |