Repository navigation
refactor: move the outbox insert and its NOTIFY into the client - #237
Merged
Merged
Conversation
AbstractOutboxClient gains insert / insert_batch. OutboxClient takes the producer's prebuilt INSERT statements and per-transaction NOTIFY memo unchanged; FakeOutboxClient stores rows with the same validation and timer_id dedup. The producer now encodes, inserts through the broker's client and emits published. A broker without an engine keeps publishing through an engine-less inserter. Part of #236.
Benchmark gate✅ gate passed
Gated (fails the build): |
SQLAlchemy 2.0.0 binds String(255) values as $1::VARCHAR(255), and Postgres truncates an explicit cast instead of raising, so the real client does not reject over-long queue or timer_id there.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
First of two PRs for #236. This one moves the outbox INSERT and its NOTIFY behind the client interface, with no user-visible change. The second PR switches
TestOutboxBrokerto the real producer.Why
TestOutboxBrokercan only run the production producer if inserts go through something it can swap. The test broker already swaps the client, so the insert moves there, next to fetch and the terminal writes.The change
AbstractOutboxClient.insert/insert_batchtake the caller's session.insertreturns the row id, orNonewhen a live row holds thetimer_id. Their docstrings point callers tobroker.publish, because calling them directly skips publish middlewares and thepublishedmetric.OutboxClienttakes over the producer's eight prebuilt INSERT statements, the batchSELECT pg_notifyand the per-transaction NOTIFY memo. The SQL is moved verbatim.OutboxProducerkeeps encoding and thepublishedevent, and inserts throughbroker_config.client, read on each publish.FakeOutboxClientgets the same operations: the existing Postgres-style validation, ids, andtimer_iddedup. A batch with one rejected row stores nothing.Brokers without an engine
#236 says to always build
OutboxClientwith an optional engine. I didn't.broker_config.client is Noneis what the broker and subscriber use for "not connected" (five places), and the test broker also runs without an engine, so "no engine" can't mean "not connected".Instead the SQL lives in a small
_OutboxInserterthat needs no engine.OutboxClientuses it, and the producer falls back to its own instance when the broker has no client. A broker without an engine keeps publishing on the caller's session, as it does today.Tests
Contract suite: new insert scenarios run against both clients, real Postgres and the fake.
Noneon a livetimer_idconflict, and the sametimer_idon another queue;timer_idreuse after delivery;activate_ingating,activate_atstored as given, and a pastactivate_ateligible at once;ValueErrorand Postgres raises a SQLAlchemyStatementError.Over-long
queueandtimer_idaren't in the contract. SQLAlchemy 2.0.0 binds them as$1::VARCHAR(255), and Postgres truncates an explicit cast instead of raising, so the real client doesn't reject them on every supported version.queueis validated before the INSERT anyway;timer_idisn't, which I'll fix in a separate PR.They failed before the change, since neither client had
insert.Integration:
test_broker_without_engine_publishes_on_the_callers_sessioncovers a single publish and a batch publish on a real session, with one NOTIFY. It also passes onmain; it's there to guard the fallback.Unchanged: the existing NOTIFY dedup tests (savepoints, autobegin, batch after single, timer conflicts) pass unchanged.
Verification
ruffandtyare clean.just bench-checkpasses with unchanged counters.