fix(backend): the reminder and at-risk polls pass over what was already sent (#1115) #1118
Loading…
Reference in a new issue
No description provided.
Delete branch "fix/1115-reminder-poll-rollback"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #1115.
Cause
Both polls claim an "already told" marker by inserting it and catching
IntegrityError, and the handler calledawait db.rollback().task_session()setsexpire_on_commit=False, which does not cover rollback: every loaded row was expired, and the log line'ssession.idthen raisedMissingGreenletand ended the task. "Already told" is what every poll after the first finds, so:poll_session_at_risk(since 3.6.0) stopped at the first already-warned session, and the sessions after it in the list were not checked.poll_session_reminders(since 1.1.0) did the same for the minutes after a reminder went out.Seen on dev (1,152 failures of the at-risk poll in four days) and on prod 4.4.1 (15 of the reminder poll on 7 October).
Fix
db.begin_nested()): a duplicate undoes the insert and nothing else.Tests
tests/test_poll_marker_claims.py(new, four tests) commits real rows and lets the polls open the realtask_session(). The existing tests could not see this: the test session aliasescommittoflush, so the rows were never persistent, and a rollback expunged them with their values loaded instead of expiring them. On main's code all four fail withMissingGreenlet; with the fix they pass.test_at_risk_task_notifies_once_per_confirmed_timenow asserts the marker survives the second run.Run before this PR: the four new tests (fail on main, pass here), 202 related backend tests, ruff. The full suite is CI's.
Not in this PR:
import_jobs.Heartbeatrolls back after a failed heartbeat write; whether anything reads an expired row afterwards was not traced.🤖 Generated with Claude Code