summaryrefslogtreecommitdiff
path: root/src/meetingtools/ac
diff options
context:
space:
mode:
authorLeif Johansson <leifj@sunet.se>2012-02-09 00:16:16 +0100
committerLeif Johansson <leifj@sunet.se>2012-02-09 00:16:16 +0100
commitad21e8e4e5ac8f9eb38830f3024e19fd9329e288 (patch)
tree4aa7d7c3a6cd66cae59708e5bba274ce1cdb1eba /src/meetingtools/ac
parent635d92fc5ded0faec71849554224608f0424fae2 (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__.py86
-rw-r--r--src/meetingtools/ac/api.py17
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: