diff --git a/src/core/management/commands/housekeeping.py b/src/core/management/commands/housekeeping.py index 6eb9106ed954662506dd8087d5f76298e27b26ce..7143ecdeef87bd98ca147bd23fa9724a49f6dc9d 100644 --- a/src/core/management/commands/housekeeping.py +++ b/src/core/management/commands/housekeeping.py @@ -1,10 +1,12 @@ import time from django.core.management.base import BaseCommand, CommandError +from django.db.models import Max from django.utils import timezone +from ...models.conference import Conference from ...models.messages import DirectMessage -from ...models.schedules import ScheduleSource, ScheduleSourceImport +from ...models.schedules import CachedSchedule, ScheduleSource, ScheduleSourceImport from ...models.voucher import Voucher @@ -14,16 +16,24 @@ class Command(BaseCommand): parser.add_argument('--forever-delay', type=int, default=300, help='seconds to wait between housekeeping runs') def _do_housekeeping(self): + self._housekeeping_directmessages() + self._housekeeping_vouchers() + self._housekeeping_scheduleimports() + self._housekeeping_schedulecaching() + + def _housekeeping_directmessages(self): # clear all direct messages which are after their expiry date print('Deleting messages ... ', end='', flush=True) deleted_msgs_count, _ = DirectMessage.objects.filter(autodelete_after__isnull=False, autodelete_after__lte=timezone.now()).delete() print(deleted_msgs_count) + def _housekeeping_vouchers(self): # do auto-assignments print('Auto-assigning vouchers ... ', end='', flush=True) vouchers_assigned = Voucher.do_auto_assignments() print(vouchers_assigned) + def _housekeeping_scheduleimports(self): # schedules print('Schedule imports ... ', end='', flush=True) schedule_results = {} @@ -60,6 +70,35 @@ class Command(BaseCommand): for k, v in schedule_results.items(): print(' ', k, ' => ', v, sep='') + def _housekeeping_schedulecaching(self): + ref = {} + for c in Conference.objects.all(): + ts = [] + ts.append(c.tracks.aggregate(Max('last_update'))['last_update__max']) + ts.append(c.events.aggregate(Max('last_update'))['last_update__max']) + ts.append(c.rooms.aggregate(Max('last_update'))['last_update__max']) + ref[c.id] = max([x for x in ts if x is not None], default=None) + + changed, total = 0, 0 + for entry in CachedSchedule.objects.all(): + total += 1 + + # entries already marked for regeneration don't need further action + if entry.needs_regeneration: + continue + + # ignore cache entries with a newer generation entry + ref_ts = ref[entry.conference_id] + if ref_ts is not None and entry.last_generated > ref_ts: + continue + + # flag this entry for regeneration + entry.needs_regeneration = True + entry.save(update_fields=['needs_regeneration']) + changed += 1 + + print('Flagged', changed, 'out of', total, 'cached schedules for regeneration.') + def handle(self, *args, **options): # call _do_housekeeping repeatedly (unless --forever is not set) forever = options.get('forever')