django-orchestra/orchestra/contrib/orders/tasks.py

51 lines
2.0 KiB
Python

import datetime
from celery.task.schedules import crontab
from django.apps import apps
from orchestra.contrib.tasks import periodic_task
from . import settings
@periodic_task(run_every=crontab(hour=4, minute=30), name='orders.cleanup_metrics')
def cleanup_metrics():
from .models import MetricStorage, Order
Service = apps.get_model(settings.ORDERS_SERVICE_MODEL)
# General cleaning: order.billed_on-delta
general = 0
delta = datetime.timedelta(days=settings.ORDERS_BILLED_METRIC_CLEANUP_DAYS)
for order in Order.objects.filter(billed_on__isnull=False):
epoch = order.billed_on-delta
try:
latest = order.metrics.filter(updated_on__lt=epoch).latest('updated_on')
except MetricStorage.DoesNotExist:
pass
else:
general += order.metrics.exclude(pk=latest.pk).filter(updated_on__lt=epoch).count()
order.metrics.exclude(pk=latest.pk).filter(updated_on__lt=epoch).only('id').delete()
# Reduce monthly metrics to latest
monthly = 0
monthly_services = Service.objects.exclude(metric='').filter(
billing_period=Service.MONTHLY, pricing_period=Service.BILLING_PERIOD
)
for service in monthly_services:
for order in Order.objects.filter(service=service):
dates = order.metrics.values_list('created_on', flat=True)
months = set((date.year, date.month) for date in dates)
for year, month in months:
metrics = order.metrics.filter(
created_on__year=year, created_on__month=month,
updated_on__year=year, updated_on__month=month)
try:
latest = metrics.latest('updated_on')
except MetricStorage.DoesNotExist:
pass
else:
monthly += metrics.exclude(pk=latest.pk).count()
metrics.exclude(pk=latest.pk).only('id').delete()
return (general, monthly)