summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeif Johansson <leifj@sunet.se>2012-02-07 09:13:04 +0100
committerLeif Johansson <leifj@sunet.se>2012-02-07 09:13:04 +0100
commitcfe4ddee2dff06465bf8c66e2e793ae1cf4368d5 (patch)
treee55a2da7dadd65151907e6a45e48514d09110dec
parent4b3351e3e37eec11285ae47163df70c669fd19ea (diff)
improved user count polling
-rw-r--r--src/meetingtools/ac/api.py23
-rw-r--r--src/meetingtools/apps/room/tasks.py56
-rw-r--r--src/meetingtools/apps/room/views.py24
-rw-r--r--src/meetingtools/settings.py6
4 files changed, 50 insertions, 59 deletions
diff --git a/src/meetingtools/ac/api.py b/src/meetingtools/ac/api.py
index ebf38ea..0be2e6a 100644
--- a/src/meetingtools/ac/api.py
+++ b/src/meetingtools/ac/api.py
@@ -14,6 +14,7 @@ from lxml import etree
from meetingtools.site_logging import logger
import lxml
from django.http import HttpResponseRedirect
+from celery.execute import send_task
class ACPException(Exception):
def __init__(self, value):
@@ -176,4 +177,24 @@ class ACPClient():
return self.add_remove_member(principal_id, group_id, True)
def remove_member(self,principal_id,group_id):
- return self.add_remove_member(principal_id, group_id, False) \ No newline at end of file
+ return self.add_remove_member(principal_id, group_id, False)
+
+ def user_counts(self,sco_id):
+ user_count = None
+ host_count = None
+ userlist = self.request('meeting-usermanager-user-list',{'sco-id': sco_id},False)
+ if userlist.status_code() == 'ok':
+ user_count = int(userlist.et.xpath("count(.//userdetails)"))
+ host_count = int(userlist.et.xpath("count(.//userdetails/role[text() = 'host'])"))
+ elif userlist.status_code() == 'no-access' and userlist.subcode() == 'not-available': #no active session
+ user_count = 0
+ host_count = 0
+
+ return (user_count,host_count)
+
+ def poll_user_counts(self,room,recheck=0):
+ (room.user_count,room.host_count) = self.user_counts(room.sco_id)
+ room.save()
+ if room.user_count > 0 or recheck > 0:
+ logging.debug("will recheck %d more times ..." % (recheck -1))
+ send_task('meetingtools.apps.room.tasks.poll_user_counts',[room],{'recheck': recheck-1},countdown=2) \ No newline at end of file
diff --git a/src/meetingtools/apps/room/tasks.py b/src/meetingtools/apps/room/tasks.py
index 0d638a6..25876eb 100644
--- a/src/meetingtools/apps/room/tasks.py
+++ b/src/meetingtools/apps/room/tasks.py
@@ -3,7 +3,7 @@ Created on Jan 18, 2012
@author: leifj
'''
-from celery.task import periodic_task
+from celery.task import periodic_task,task
from celery.schedules import crontab
from meetingtools.apps.cluster.models import ACCluster
from meetingtools.ac import ac_api_client, ac_api_client_nocache,\
@@ -16,6 +16,7 @@ from django.core.exceptions import ObjectDoesNotExist
import logging
from datetime import datetime,timedelta
from lxml import etree
+from django.db.models import Q
def _owner_username(api,sco):
logging.debug(sco)
@@ -110,12 +111,7 @@ def _import_one_room(acc,api,row):
room.source_sco_id = source_sco_id
room.description = description
room.urlpath = urlpath
-
- userlist = api.request('meeting-usermanager-user-list',{'sco-id': room.sco_id},False)
- if userlist.status_code() == 'ok':
- room.user_count = int(userlist.et.xpath("count(.//userdetails)"))
- room.host_count = int(userlist.et.xpath("count(.//userdetails/role[text() = 'host'])"))
-
+
room.save()
room.unlock()
else:
@@ -130,40 +126,22 @@ def _import_acc(acc):
for row in r.et.xpath("//row"):
_import_one_room(acc,api,row)
-
@periodic_task(run_every=crontab(hour="*", minute="*/1", day_of_week="*"))
def import_all_rooms():
for acc in ACCluster.objects.all():
_import_acc(acc)
-
-def _import_meeting_room_usercount(api,acc,sco_id,row=None,room=None):
- try:
- if room == None:
- room = Room.objects.get(acc=acc,sco_id=sco_id)
-
- if row and row.findtext("date-end"):
- room.user_count = 0
- room.host_count = 0
- else:
- userlist = api.request('meeting-usermanager-user-list',{'sco-id': room.sco_id},False)
- if userlist.status_code() == 'ok':
- room.user_count = int(userlist.et.xpath("count(.//userdetails)"))
- room.host_count = int(userlist.et.xpath("count(.//userdetails/role[text() = 'host'])"))
- elif userlist.status_code() == 'no-access' and userlist.subcode() == 'not-available': #no active session
- room.user_count = 0
- room.host_count = 0
- room.save()
- except ObjectDoesNotExist:
- pass
-
-def _import_user_counts_acc(acc):
- api = ac_api_client_direct(acc)
- for room in Room.objects.filter(acc=acc,user_count=None):
- _import_meeting_room_usercount(api,acc,room.sco_id,None,room)
- for room in Room.objects.filter(acc=acc,user_count__gt=0):
- _import_meeting_room_usercount(api,acc,room.sco_id,None,room)
-
-@periodic_task(run_every=crontab(hour="*", minute="*/1", day_of_week="*"))
-def import_user_counts():
+
+@task(name='meetingtools.apps.room.tasks.poll_user_counts',rate_limit="10/s")
+def poll_user_counts(room,recheck=0):
+ logging.debug("rechecking user_counts for room %s" % room.name)
+ api = ac_api_client_direct(room.acc)
+ api.poll_user_counts(room,recheck)
+
+# belts and suspenders - we setup polling for active rooms aswell...
+@periodic_task(run_every=crontab(hour="*", minute="*/5", day_of_week="*"))
+def import_recent_user_counts():
for acc in ACCluster.objects.all():
- _import_user_counts_acc(acc) \ No newline at end of file
+ api = ac_api_client_direct(acc)
+ then = datetime.now()-timedelta(seconds=600)
+ for room in Room.objects.filter((Q(lastupdated__gt=then) | Q(lastvisited__gt=then)) & Q(acc=acc)):
+ api.poll_user_counts(room) \ No newline at end of file
diff --git a/src/meetingtools/apps/room/views.py b/src/meetingtools/apps/room/views.py
index 264ccc5..8ba25c2 100644
--- a/src/meetingtools/apps/room/views.py
+++ b/src/meetingtools/apps/room/views.py
@@ -30,6 +30,8 @@ from django.utils.feedgenerator import rfc3339_date
from django.views.decorators.cache import cache_control, never_cache
from meetingtools.apps.cluster.models import acc_for_user
from django.contrib.auth.models import User
+import iso8601
+from celery.execute import send_task
def _user_meeting_folder(request,acc):
if not session(request,'my_meetings_sco_id'):
@@ -389,17 +391,10 @@ def _goto(request,room,clean=True,promote=False):
lastvisit = room.lastvisit()
room.lastvisited = datetime.now()
+ api.poll_user_counts(room)
if clean:
- room.user_count = None
- room.host_count = None
- userlist = api.request('meeting-usermanager-user-list',{'sco-id': room.sco_id},False)
- if userlist.status_code() == 'ok':
- room.user_count = int(userlist.et.xpath("count(.//userdetails)"))
- room.host_count = int(userlist.et.xpath("count(.//userdetails/role[text() = 'host'])"))
-
- logging.debug("---------- nusers: %s" % room.user_count)
- room.save()
- if room.self_cleaning and userlist.status_code() == 'ok': # don't clean the room unless you get a good status code
+ # don't clean the room unless you get a good status code from the call to the usermanager api above
+ if room.self_cleaning and room.user_count == 0:
if (room.user_count == 0) and (abs(lastvisit - now) > GRACE):
room.lock("Locked for cleaning")
try:
@@ -426,6 +421,7 @@ def _goto(request,room,clean=True,promote=False):
r = api.request('sco-info',{'sco-id':room.sco_id},True)
urlpath = r.et.findtext('.//sco/url-path')
+ api.poll_user_counts(room,recheck=5)
if key:
try:
user_client = ACPClient(room.acc.api_url, request.user.username, key, cache=False)
@@ -523,10 +519,6 @@ def tag(request,rid):
{'text/html': "apps/room/tag.html"},
{'form': form,'formtitle': 'Add Tag','cancelname':'Done','submitname': 'Add Tag','room': room, 'tagstring': tn,'tags': tags})
-
-from time import mktime
-from feedparser import _parse_date as parse_date
-
def room_recordings(request,room):
api = ac_api_client(request, room.acc)
r = api.request('sco-expanded-contents',{'sco-id': room.sco_id,'filter-icon':'archive'},True)
@@ -534,8 +526,8 @@ def room_recordings(request,room):
'sco_id': sco.get('sco-id'),
'url': room.acc.make_url(sco.findtext('url-path')),
'description': sco.findtext('description'),
- 'date_created': datetime.fromtimestamp(mktime(parse_date(sco.findtext('date-created')))),
- 'date_modified': datetime.fromtimestamp(mktime(parse_date(sco.findtext('date-modified'))))} for sco in r.et.findall(".//sco")]
+ 'date_created': iso8601.parse_date(sco.findtext('date-created')),
+ 'date_modified': iso8601.parse_date(sco.findtext('date-modified'))} for sco in r.et.findall(".//sco")]
@login_required
def recordings(request,rid):
diff --git a/src/meetingtools/settings.py b/src/meetingtools/settings.py
index 46c3d72..4706503 100644
--- a/src/meetingtools/settings.py
+++ b/src/meetingtools/settings.py
@@ -69,9 +69,9 @@ LOGOUT_URL = "%s/accounts/logout" % PREFIX_URL
# Make this unique, and don't share it with anybody.
SECRET_KEY = 'tz78l!c=cl2=jic5$2#(bq)7-4s1ivtm*a+q0w1yi0$)hrmc7l'
-#SESSION_ENGINE = "django.contrib.sessions.backends.file"
-SESSION_ENGINE = "django.contrib.sessions.backends.cache"
-#SESSION_FILE_PATH = "/tmp"
+SESSION_ENGINE = "django.contrib.sessions.backends.file"
+#SESSION_ENGINE = "django.contrib.sessions.backends.cache"
+SESSION_FILE_PATH = "/tmp"
SESSION_EXPIRE_AT_BROWSER_CLOSE = True
CACHES = {