From 8ed612eeae60a7c645d3d14aa3348714a4ef951b Mon Sep 17 00:00:00 2001 From: =?utf8?q?Stefan=20K=C3=B6gl?= Date: Sat, 27 Apr 2013 15:57:07 +0200 Subject: [PATCH] handle large episode action uploads in background --- mygpo/api/advanced/__init__.py | 19 +++++++++++++++++++ mygpo/api/tasks.py | 10 ++++++++++ mygpo/cel.py | 1 + mygpo/settings.py | 6 ++++++ 4 files changed, 36 insertions(+) create mode 100644 mygpo/api/tasks.py diff --git a/mygpo/api/advanced/__init__.py b/mygpo/api/advanced/__init__.py index 636f8590..4e406a24 100644 --- a/mygpo/api/advanced/__init__.py +++ b/mygpo/api/advanced/__init__.py @@ -19,6 +19,7 @@ from functools import partial from itertools import imap, chain from collections import defaultdict, namedtuple from datetime import datetime +from importlib import import_module import dateutil.parser @@ -33,6 +34,7 @@ from django.views.decorators.csrf import csrf_exempt from django.views.decorators.cache import never_cache from django.utils.decorators import method_decorator from django.views.generic.base import View +from django.conf import settings from mygpo.api.constants import EPISODE_ACTION_TYPES, DEVICE_TYPES from mygpo.api.httpresponse import JsonResponse @@ -187,6 +189,23 @@ def episodes(request, username, version=1): log(msg) return HttpResponseBadRequest(msg) + log('start: user %s: %d actions from %s' % (request.user._id, len(actions), ua_string)) + + # handle in background + if len(actions) > settings.API_ACTIONS_MAX_NONBG: + bg_handler = settings.API_ACTIONS_BG_HANDLER + if bg_handler is not None: + + modname, funname = bg_handler.rsplit('.', 1) + mod = import_module(modname) + fun = getattr(mod, funname) + + fun(request.user, actions, now, ua_string) + + # TODO: return 202 Accepted + return JsonResponse({'timestamp': now_, 'update_urls': []}) + + try: update_urls = update_episodes(request.user, actions, now, ua_string) except DeviceUIDException as e: diff --git a/mygpo/api/tasks.py b/mygpo/api/tasks.py new file mode 100644 index 00000000..32058834 --- /dev/null +++ b/mygpo/api/tasks.py @@ -0,0 +1,10 @@ +from mygpo.cel import celery +from mygpo.api.advanced import update_episodes + + +@celery.task(max_retries=5, default_retry_delay=60) +def import_episode_actions(user, actions, upload_ts, ua_string): + update_episodes(user, actions, upload_ts, ua_string) + +# celery-based handler for episode-actions +episode_actions_celery_handler = import_episode_actions.delay diff --git a/mygpo/cel.py b/mygpo/cel.py index 8ee7bee9..6a61b6ab 100644 --- a/mygpo/cel.py +++ b/mygpo/cel.py @@ -13,6 +13,7 @@ celery = Celery('mygpo.celery', backend=settings.BACKEND_URL, include=[ 'mygpo.core.tasks', + 'mygpo.api.tasks', 'mygpo.users.tasks', 'mygpo.data.tasks', 'mygpo.admin.tasks', diff --git a/mygpo/settings.py b/mygpo/settings.py index 59fbc948..520bc774 100644 --- a/mygpo/settings.py +++ b/mygpo/settings.py @@ -193,6 +193,12 @@ PODCAST_SLUG_SUBSCRIBER_LIMIT = 10 # categories to the top MIN_SUBSCRIBERS_CATEGORY=10 +# maximum number of episode actions that the API processes immediatelly before +# returning the response. Larger requests will be handled in background. +# Handler can be set to None to disable +API_ACTIONS_MAX_NONBG=100 +API_ACTIONS_BG_HANDLER='mygpo.api.tasks.episode_actions_celery_handler' + ADSENSE_CLIENT = '' ADSENSE_SLOT_BOTTOM = '' -- 2.11.4.GIT