Skip to content

feat(nimbus): Celery tasks to run holdback analysis weekly#16136

Open
yashikakhurana wants to merge 12 commits into
mainfrom
16086
Open

feat(nimbus): Celery tasks to run holdback analysis weekly#16136
yashikakhurana wants to merge 12 commits into
mainfrom
16086

Conversation

@yashikakhurana

Copy link
Copy Markdown
Contributor

Because

  • Holdback experiments run continuously and need Jetstream to rerun analysis weekly as the eligible population grows

This commit

  • Adds a weekly Celery task that expands the proposed_enrollment window and sets do_rerun to signal Jetstream to rerun analysis

Fixes #16086

@yashikakhurana yashikakhurana changed the title 16086 feat(nimbus): Celery tasks to run holdback analysis weekly Jun 29, 2026
@yashikakhurana

Copy link
Copy Markdown
Contributor Author

Blocked on this #16096

Comment thread experimenter/experimenter/jetstream/tasks.py
Comment thread experimenter/experimenter/jetstream/tasks.py Outdated
Comment thread experimenter/experimenter/jetstream/tasks.py Outdated
Comment thread experimenter/experimenter/jetstream/tasks.py Outdated
Comment thread experimenter/experimenter/jetstream/tasks.py Outdated
Comment thread experimenter/experimenter/settings.py
@yashikakhurana yashikakhurana requested a review from mikewilli June 30, 2026 22:45
Yashika Khurana added 6 commits June 30, 2026 15:50
…x test expectations

Holdback experiments never pause enrollment so actual_enrollment_end_date
is always None, causing the task to skip every experiment. Switch to
computed_enrollment_end_date (start_date + proposed_enrollment) which
correctly reflects when the initial enrollment window expires.

Update test comment and expected value to match the corrected calculation
(36 days since end → weeks_elapsed=5 → 14+35=49).
…back

- Run daily instead of weekly (holdbacks can launch any day)
- Use today - 21 days as rolling enrollment_end (observation period)
- Skip experiments with end_date set (actually ended holdbacks)
- Update _enrollment_end_date instead of proposed_enrollment
- Add changelog entry per updated experiment
- Compute proposedEnrollment, enrollmentEndDate, endDate on-the-fly
  in v8 serializer for active holdbacks — real fields stay untouched
- Add HOLDBACK_ENROLLMENT_UPDATED changelog message constant
@yashikakhurana yashikakhurana requested a review from RJAK11 as a code owner July 7, 2026 16:57

@mikewilli mikewilli left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggested a couple small changes, but more importantly I think there's still some confusion over which dates to fake, when to fake them, and what they should be set to. My understanding of what we want to do here isn't quite in line with what you have here, and I'm not totally sure if that's a misunderstanding on my part or if I'm just not quite explaining it clearly enough.

Let me know if you want to chat about it to try and make sure we're on the same page.

raise


HOLDBACK_OBSERVATION_DAYS = 21

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Constants shouldn't appear in the middle of the file.

def get_enrollmentEndDate(self, obj):
enrollment_end = obj.actual_enrollment_end_date
if obj.is_holdback and not obj.end_date and enrollment_end:
return enrollment_end.isoformat()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be today - 21 days, right?


def get_enrollmentEndDate(self, obj):
enrollment_end = obj.actual_enrollment_end_date
if obj.is_holdback and not obj.end_date and enrollment_end:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if obj.is_holdback and not obj.end_date and enrollment_end:
if obj.is_holdback and not obj.end_date and not enrollment_end:

def get_endDate(self, obj):
enrollment_end = obj.actual_enrollment_end_date
if obj.is_holdback and not obj.end_date and enrollment_end:
return (enrollment_end + datetime.timedelta(days=21)).isoformat()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This 21 should also be a constant, ideally the same one that we use in the jetstream task code. Maybe it can go in the django constants/settings?

is_holdback=True,
status=NimbusExperiment.Status.LIVE,
_end_date=None,
).exclude(_start_date=None)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Theoretically it shouldn't be possible for an experiment to be LIVE and have no start date, right? Not a big deal though if you think this could cover some edge case or something.

Comment on lines +224 to +228
NimbusExperiment.objects.filter(pk=experiment.pk).update(
_enrollment_end_date=enrollment_end,
do_rerun=True,
do_rerun_timestamp=now,
)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is changing the enrollment end date like this going to affect actual enrollments?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left some comments here and then went and looked at the task. I think what you have here makes sense IF it's valid to change the actual enrollment end date on the experiment, but I worry that this might break something else. I think it'd be better to assume the enrollment end date is NOT set until the experiment owner actually ends enrollment, and until then you can set a fake one in the serializer here the same way you do for the other dates.

If it is valid to change the actual enrollment end date, then maybe what you have here is ok.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Weekly task to update holdback enrollment period and trigger Jetstream rerun

2 participants