docs: document the separate-transactions rule across user-facing surfaces#190
docs: document the separate-transactions rule across user-facing surfaces#190
Conversation
…omments Per review feedback on PR #190. - Halve the prose on every per-surface callout (tutorial Step 5, examples anti-example, reference snapshot-rule paragraph). The canonical long-form lives in pgq-concepts.md#snapshot-rule and is unchanged. - Cut the three client README "Transactions" sections to ~3 sentences each. The previous versions repeated points already made on the canonical page. - Add inline -- separate transaction comments next to pgque.ticker(), pgque.force_tick(), and follow-up pgque.receive() calls in the tutorial and the fan-out example, so the rule is visible at the point of use rather than only in surrounding prose.
REV review — PR #190BLOCKING ISSUES (2)MEDIUM
MEDIUM PR mergeability — GitHub currently reports
NON-BLOCKINGNone found. EVIDENCE
VERDICTRequest changes. The core direction is good and useful, but the shared docs should not imply Python’s default |
…omments Per review feedback on PR #190. - Halve the prose on every per-surface callout (tutorial Step 5, examples anti-example, reference snapshot-rule paragraph). The canonical long-form lives in pgq-concepts.md#snapshot-rule and is unchanged. - Cut the three client README "Transactions" sections to ~3 sentences each. The previous versions repeated points already made on the canonical page. - Add inline -- separate transaction comments next to pgque.ticker(), pgque.force_tick(), and follow-up pgque.receive() calls in the tutorial and the fan-out example, so the rule is visible at the point of use rather than only in surrounding prose.
Per REV review on PR #190. The shared concepts/reference docs implied the Python client satisfies the snapshot rule transparently like Go/TS pool methods. That is wrong for the bare client: pgque.connect(dsn) is autocommit=False by default, so producers must commit explicitly between send and consumer side. The high-level Python Consumer already handles this internally; the bare PgqueClient leaves transaction management to the caller. Brings pgq-concepts.md and reference.md in line with the per-driver README and the actual psycopg default.
24f04bc to
aee895a
Compare
REV review — final sanity passVerdict: REV OK for v0.2.0. No blockers found. Checked:
Optional nit, not blocking: Coordination note: #206 touches nearby docs and introduces |
…aces
The "send → ticker → receive" snapshot rule and the related
"maint_retry_events → ticker → receive" rule were called out in test
files (test_api_receive.sql header etc.) but invisible everywhere else.
A user reading the tutorial, the function reference, or any client
README had no warning that wrapping these calls in one explicit tx
silently produces empty batches.
This commit adds the rule once in pgq-concepts.md and links to it
from every other surface that names the involved functions:
- docs/tutorial.md: short callout under Step 5 ("Force a tick, then
receive") explaining why each select runs in its own transaction.
- docs/pgq-concepts.md: new "Snapshot rule" subsection with all three
operation chains (producer → consumer; retry pump; rotation step1 →
step2) and the asymmetry vs. receive→process→ack.
- docs/examples.md: anti-example block under "Exactly-once processing"
showing the wrong send+receive-in-one-tx pattern.
- docs/reference.md: anchor + paragraph at the top of "Consuming";
inline reminders on maint_retry_events and force_tick entries.
- clients/python/README.md: new "Transactions" section explaining
default psycopg autocommit behavior, the Quickstart's commit
pattern, and the Consumer's internal transaction scope.
- clients/go/README.md: new "Transactions" section flagging
Client.Pool() as the footgun (its doc-comment invites you to
pgque.send inside your own pgx.Tx — correct only if consumer side
runs in a separate tx).
- clients/typescript/README.md: new "Transactions" section flagging
client.rawPool similarly.
No code or behavior change. Source SQL header comments
(sql/pgque-api/{send,receive,maint}.sql) intentionally left for a
later contributor-doc pass.
…omments Per review feedback on PR #190. - Halve the prose on every per-surface callout (tutorial Step 5, examples anti-example, reference snapshot-rule paragraph). The canonical long-form lives in pgq-concepts.md#snapshot-rule and is unchanged. - Cut the three client README "Transactions" sections to ~3 sentences each. The previous versions repeated points already made on the canonical page. - Add inline -- separate transaction comments next to pgque.ticker(), pgque.force_tick(), and follow-up pgque.receive() calls in the tutorial and the fan-out example, so the rule is visible at the point of use rather than only in surrounding prose.
Per REV review on PR #190. The shared concepts/reference docs implied the Python client satisfies the snapshot rule transparently like Go/TS pool methods. That is wrong for the bare client: pgque.connect(dsn) is autocommit=False by default, so producers must commit explicitly between send and consumer side. The high-level Python Consumer already handles this internally; the bare PgqueClient leaves transaction management to the caller. Brings pgq-concepts.md and reference.md in line with the per-driver README and the actual psycopg default.
aee895a to
e87630b
Compare
Rebased on current
|
Documents the snapshot-based separate-transactions rule across user-facing surfaces. Pure docs, no code change.
Why
While implementing PR #179 (#134), I hit the rule myself: three operations in one
do$$block silently returned 0 rows on the nextreceive(). Auditing the codebase showed the rule is consistently called out in test headers (test_api_receive.sql,test_core_events.sql,test_core_retry.sql,test_core_batch_retry.sql, etc.) but invisible everywhere a user actually reads:docs/tutorial.mdpromises ("when transaction boundaries matter, the text calls that out") but never does.docs/pgq-concepts.md,docs/reference.md,docs/examples.md— no mention.clients/{python,go,typescript}/README.md— no mention. The Go README explicitly invites the footgun ("callpgque.sendinside your ownpgx.Tx") with no warning that mixing send + receive in one Tx breaks.Followed by
CLAUDE.mdKey Design Rule #7 added in PR #179, this PR makes the same rule visible to humans.What
The rule lives once, in
docs/pgq-concepts.md#snapshot-rule, with the three operation chains and the asymmetry vs.receive → process → ack. Every other surface gets a short callout that links there.docs/pgq-concepts.mddocs/tutorial.mddocs/examples.mdsend + force_tick + ticker + receivein onebegin/commitreturns 0 rowsdocs/reference.mdmaint_retry_eventsandforce_tickclients/python/README.mdpgque.connectdefaults toautocommit=False; explains Consumer's autocommit + explicit-tx-around-receive+ack pattern.clients/go/README.mdClient.Pool()as the footgun (its existing doc invitespgque.sendinside your ownpgx.Tx— correct only if consumer side runs in a separate tx).clients/typescript/README.mdclient.rawPoolsimilarly.Out of scope
sql/pgque-api/{send,receive,maint}.sql— useful for contributors reading source, but a separate audience and a separate concern. Left for a later pass.CLAUDE.mdalready has the rule as Key Design Rule feat: add pgque-specific schema additions #7 (added in PR fix(receive): re-queue unreturned batch rows on ack (#134) #179).Test plan
Refs PR #179.
Generated by Claude Code