Skip to content

Commit 5dba100

Browse files
authored
docs: timers are due by the database clock, and activate_in counts from transaction start (#253)
1 parent 94d750b commit 5dba100

1 file changed

Lines changed: 11 additions & 5 deletions

File tree

‎docs/usage/timers.md‎

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,18 @@ explicit `ValueError` rather than guessing your intended zone.
4646

4747
### Server-side vs client-side scheduling
4848

49+
The fetch query compares `next_attempt_at` with the database's `now()`, so
50+
the database clock decides when a row is due.
51+
4952
For `publish` with `activate_in`, `next_attempt_at` is computed server-side
50-
via `now() + make_interval(secs => :s)` to stay clock-skew-safe. With
51-
`activate_at`, you supply an absolute instant, so it is stored verbatim and
52-
compared against the *worker's* clock at fetch time. Only `activate_in` is
53-
skew-safe; `activate_at` is as accurate as your producers' and workers'
54-
clocks agree. For `publish_batch`, `activate_in` is also client-side
53+
via `now() + make_interval(secs => :s)` to stay clock-skew-safe. In
54+
PostgreSQL, `now()` is the start time of the current transaction, so the
55+
deadline counts from when the caller's transaction began, not from the
56+
`publish` call. Keep publishing transactions short if that gap matters.
57+
With `activate_at`, you supply an absolute instant, so it is stored verbatim
58+
and compared against the database clock. Only `activate_in` is skew-safe;
59+
`activate_at` is as accurate as your producers' and the database's clocks
60+
agree. For `publish_batch`, `activate_in` is also client-side
5561
(`datetime.now(UTC) + activate_in`) because executemany doesn't compose
5662
cleanly with column-level SQL expressions, and the few-ms drift is harmless
5763
for user-supplied scheduling.

0 commit comments

Comments
 (0)