From c267e38bdabe5ddcb9e48b81d394ca5bcd8bf0b0 Mon Sep 17 00:00:00 2001 From: Mark Story Date: Tue, 27 May 2025 17:32:12 -0400 Subject: [PATCH] fix(taskworker) Update parameters for update_user_reports I'm trying to tighten our task + pickle support to also include direct calls to task functions. The update_user_report task had several parameters that cannot be JSON encoded. I've replaced the problematic parameters with JSON compatible ones, and updated logic accordingly. While these signatures would normally be breaking changes, this task *is only* triggered from celerybeat and thus never gets any parameters. --- src/sentry/tasks/update_user_reports.py | 30 ++++++++++++------- .../sentry/tasks/test_update_user_reports.py | 14 +++++++-- 2 files changed, 31 insertions(+), 13 deletions(-) diff --git a/src/sentry/tasks/update_user_reports.py b/src/sentry/tasks/update_user_reports.py index 07711127e58103..1a075ccbfd9327 100644 --- a/src/sentry/tasks/update_user_reports.py +++ b/src/sentry/tasks/update_user_reports.py @@ -1,6 +1,5 @@ import logging -from datetime import timedelta -from typing import Any +from datetime import datetime, timedelta import sentry_sdk from django.utils import timezone @@ -31,13 +30,26 @@ namespace=issues_tasks, ), ) -def update_user_reports(**kwargs: Any) -> None: +def update_user_reports( + start_datetime: str | None = None, + end_datetime: str | None = None, + max_events: int | None = None, + event_lookback_days: int | None = None, +) -> None: now = timezone.now() - start = kwargs.get("start", now - timedelta(days=1)) - end = kwargs.get("end", now + timedelta(minutes=5)) # +5 minutes just to catch clock skew + start = now - timedelta(days=1) + # +5 minutes just to catch clock skew + end = now + timedelta(minutes=5) + + if start_datetime: + start = datetime.fromisoformat(start_datetime) + if end_datetime: + end = datetime.fromisoformat(end_datetime) # The event query time range is [start - event_lookback, end]. - event_lookback = kwargs.get("event_lookback", timedelta(days=1)) + if event_lookback_days is None: + event_lookback_days = 1 + event_lookback = timedelta(days=event_lookback_days) # Filter for user reports where there was no event associated with them at # ingestion time @@ -57,10 +69,8 @@ def update_user_reports(**kwargs: Any) -> None: updated_reports = 0 samples = None - MAX_EVENTS = kwargs.get( - "max_events", - 2000, # the default max_query_size is 256 KiB, which we're hitting with 5000 events, so keeping it safe at 2000 - ) + # the default max_query_size is 256 KiB, which we're hitting with 5000 events, so keeping it safe at 2000 + MAX_EVENTS = max_events or 2000 for project_id, reports in project_map.items(): project = Project.objects.get(id=project_id) event_ids = [r.event_id for r in reports] diff --git a/tests/sentry/tasks/test_update_user_reports.py b/tests/sentry/tasks/test_update_user_reports.py index a02d50c8be265c..794f7f9e5e8265 100644 --- a/tests/sentry/tasks/test_update_user_reports.py +++ b/tests/sentry/tasks/test_update_user_reports.py @@ -64,7 +64,7 @@ def test_report_timerange(self): ) with self.tasks(): - update_user_reports(start=start, end=end) + update_user_reports(start_datetime=start.isoformat(), end_datetime=end.isoformat()) report1 = UserReport.objects.get(project_id=project.id, event_id=event1.event_id) report2 = UserReport.objects.get(project_id=project.id, event_id=event2.event_id) @@ -106,7 +106,11 @@ def test_event_timerange(self): ) with self.tasks(): - update_user_reports(start=start, end=end, event_lookback=event_lookback) + update_user_reports( + start_datetime=start.isoformat(), + end_datetime=end.isoformat(), + event_lookback_days=event_lookback.days, + ) report1 = UserReport.objects.get(project_id=project.id, event_id=event1.event_id) report2 = UserReport.objects.get(project_id=project.id, event_id=event2.event_id) @@ -207,7 +211,11 @@ def test_event_retention(self, mock_get_event_retention): self.create_event_and_report(project.id, event_dt=event_dt, report_dt=report_dt) with self.tasks(): - update_user_reports(start=epoch, end=now, event_lookback=event_lookback) + update_user_reports( + start_datetime=epoch.isoformat(), + end_datetime=now.isoformat(), + event_lookback_days=event_lookback.days, + ) assert mock_get_event_retention.call_count > 0 report = UserReport.objects.get()