diff options
author | Leif Johansson <leifj@sunet.se> | 2012-02-07 09:13:04 +0100 |
---|---|---|
committer | Leif Johansson <leifj@sunet.se> | 2012-02-07 09:13:04 +0100 |
commit | cfe4ddee2dff06465bf8c66e2e793ae1cf4368d5 (patch) | |
tree | e55a2da7dadd65151907e6a45e48514d09110dec /src | |
parent | 4b3351e3e37eec11285ae47163df70c669fd19ea (diff) |
improved user count polling
Diffstat (limited to 'src')
-rw-r--r-- | src/meetingtools/ac/api.py | 23 | ||||
-rw-r--r-- | src/meetingtools/apps/room/tasks.py | 56 | ||||
-rw-r--r-- | src/meetingtools/apps/room/views.py | 24 | ||||
-rw-r--r-- | src/meetingtools/settings.py | 6 |
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 = { |