Skip to content

chore(deps)!: bump obix to 0.11.0, job to 0.14.0 - #884

Merged
bodymindarts merged 2 commits into
mainfrom
chore/bump-obix-0.11-job-0.14
Sep 16, 2026
Merged

bodymindarts merged 2 commits into
mainfrom
chore/bump-obix-0.11-job-0.14

Conversation

@bodymindarts

@bodymindarts bodymindarts commented Sep 16, 2026

Copy link
Copy Markdown
Member

What

dep from to
obix 0.10.0 0.11.0
job 0.13.17 0.14.0

Both are breaking 0.x minor bumps:

Migration — updated in place

Nothing is live yet, so the obix setup migration is regenerated in place rather than adding a drop/add migration.

The new file is a faithful cala_-prefixed copy of the obix 0.11.0 template, verified by round-trip: stripping cala_ reproduces upstream byte for byte. Prefixes are applied to DDL identifiers only; comment prose is upstream verbatim (which is why the comment diff is noisy — the previous copy had hand-abridged comments).

Schema delta from 0.10.0:

  • commit_xid BIGINT NOT NULL DEFAULT pg_current_xact_id()::text::bigint on cala_persistent_outbox_events, plus an index on it
  • new commit-log lane: cala_persistent_outbox_commit_log (range-partitioned, with _p0 + _default partitions and a sequence index) and the singleton cala_persistent_outbox_commit_log_state seeded with (0, 0)

20250904065521_job_setup.sql is already identical to job 0.14.0's copy — unchanged.

Source change

SingletonSubscriber::handle_persistent now takes &Arc<PersistentOutboxEvent<P>> (the shared Arc the outbox decoded once) instead of &PersistentOutboxEvent<P>. Updated the EC rollup handler's signature to match; Arc<T> derefs to T, so the body is unchanged.

Not done here: the new Arc makes it possible for collect_with folds to retain a refcount instead of cloning fields out of the event. The handler still clones entry_ids/entry as before — worth a follow-up, but out of scope for a version bump.

Verified locally

  • make reset-deps — migration applies cleanly from scratch
  • .sqlx regenerated via make sqlx-prepare (10 new commit-log queries cached)
  • SQLX_OFFLINE=true cargo build --locked (what CI builds) — passes
  • cargo clippy --workspace --all-targets --all-features — clean; the one unused_mut warning in tests/transaction_batch.rs:814 is pre-existing on main (confirmed by stashing)
  • make check-event-schemas — schemas unchanged

Full test suite left to CI.

🤖 Generated with Claude Code


Note

High Risk
Touches persistent outbox schema/commit ordering, job queue SQL under concurrency, and the EC rollup hot path—core async infrastructure where regressions affect delivery correctness and balance maintenance.

Overview
Bumps obix to 0.11.0 and job to 0.14.0, with workspace lockfile updates and a regenerated .sqlx offline cache (outbox queries now surface commit_xid; job-execution SQL reflects upstream locking, batching, and idempotency changes).

The obix setup migration is rewritten in place for greenfield deploys: commit_xid (and index) on cala_persistent_outbox_events, plus the new commit-ordered delivery lane (cala_persistent_outbox_commit_log, singleton state, partitions/indexes). Subscription DDL comments are expanded; behavior is unchanged aside from schema alignment with obix 0.11.

EC balance rollup adapts to obix’s handle_persistent(&Arc<PersistentOutboxEvent<…>>) API and avoids cloning stream payloads: transactions keep an Arc to the shared event (entry ids read from payload), batches store Arc entry events, and EcRollupTxn / balance appliers take borrowed &EntryValues through flush instead of owned vectors.

Reviewed by Cursor Bugbot for commit 9817393. Bugbot is set up for automated code reviews on this repo. Configure here.

bodymindarts and others added 2 commits September 16, 2026 09:09
obix 0.11.0 adds commit-ordered delivery as an opt-in second lane
(#151); job 0.14.0 returns the existing job for duplicate requests
(#214). Both are breaking 0.x minor bumps.

Migration updated in place from the obix 0.11.0 template (nothing is
live yet, so no drop/add migration is needed). The regenerated file is
a faithful cala_-prefixed copy of the upstream template, verified by
round-trip: stripping the prefix reproduces it byte for byte. The new
schema adds commit_xid to the events table plus the commit-log lane
(partitioned log, its partitions, and the singleton state row).

SingletonSubscriber::handle_persistent now receives the event as the
shared Arc the outbox decoded once, so the EC rollup handler's
signature is updated to match; Arc derefs, so the body is unchanged.

.sqlx cache regenerated against the new schema.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
obix 0.11.0 delivers each persistent event as the Arc it decoded once,
so a collect_with fold can retain a refcount instead of copying the
payload out. The rollup batch now holds those Arcs:

- EntryCreated: was a full EntryValues clone per entry per batch
  (Decimal, Currency, description, metadata JSON). Stragglers whose
  transaction flushed in an earlier landing were cloned and then
  dropped, which is pure waste.
- TransactionCreated: was a Vec<EntryId> allocation per transaction.
  The Copy scalars are still copied out; entry_ids is read back
  through the event.

Nothing downstream needed owned entries — the applier stores
&'a EntryValues in SnapshotOrEntry and only reads them — so
EcRollupTxn now carries Vec<&'a EntryValues>, borrowed either from the
batch's events or from the flush's fetched map. Both outlive the
apply call. Snapshots::from_ec_entries takes an IntoIterator of
&EntryValues; &Vec<EntryValues> still satisfies it, so its existing
callers are unchanged.

into_rollup_txns becomes rollup_txns(&self, &fetched). It reads the
maps instead of draining them; entry ids are unique to one
transaction, so get and remove are equivalent here.

104 tests pass (lib, ec_streaming_rollup, effective_balance).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@bodymindarts

Copy link
Copy Markdown
Member Author

Pushed 9817393b — the Arc follow-up from the description, now done rather than deferred.

What changed. The batch retains the shared events instead of copying payloads out of them:

  • EntryCreated was a full EntryValues clone per entry per batch (Decimal, Currency, description, metadata JSON). Stragglers whose transaction flushed in an earlier landing were cloned and then dropped — pure waste.
  • TransactionCreated was a Vec<EntryId> allocation per transaction. The Copy scalars are still copied out; entry_ids is read back through the event.

Why it reaches all the way down. Nothing downstream ever needed owned entries — the applier stores &'a EntryValues in SnapshotOrEntry and only reads them. So EcRollupTxn now carries Vec<&'a EntryValues>, borrowed either from the batch's events or from the flush's fetched map, both of which outlive the apply call. That makes the path zero-copy rather than just moving the clone later.

Snapshots::from_ec_entries now takes an IntoIterator<Item = &EntryValues>; &Vec<EntryValues> already satisfies that, so its six existing callers are untouched.

One thing worth a reviewer's eye: into_rollup_txns became rollup_txns(&self, &fetched) and reads the maps instead of draining them (get where it used remove). Those are equivalent because an entry id belongs to exactly one transaction, so the per-transaction id sets are disjoint — but it is the one place where the refactor changes more than types.

Verified: cargo clippy --all-targets --all-features clean (fuzz harness included — it now synthesizes events), and 104 tests pass across --lib, ec_streaming_rollup, and effective_balance. Full suite still left to CI.

@github-actions

github-actions Bot commented Sep 16, 2026

Copy link
Copy Markdown
Contributor

📊 Performance Report

Commit: 9817393
Updated: 2026-09-16 07:35:13 UTC

Cala Performance Benchmark Results (non-representative)

Criterion Benchmark Results (single-threaded)

Benchmark Time per Run Throughput % vs Baseline
post_simple_transaction 3.300ms 302 tx/s 0 (baseline)
post_multi_layer_transaction 3.730ms 268 tx/s -13.0%
post_simple_transaction_with_effective_balances 4.816ms 207 tx/s -45.0%
post_simple_transaction_with_skipped_velocity 2.731ms 366 tx/s +17.0%
post_simple_transaction_with_velocity 3.569ms 280 tx/s -8.0%
post_simple_transaction_with_hit_velocity 1.533ms 652 tx/s +53.0%
post_simple_transaction_with_one_account_set 3.110ms 321 tx/s +5.0%
post_simple_transaction_with_five_account_sets 4.516ms 221 tx/s -36.0%
post_simple_transaction_with_ec_account_set 2.812ms 355 tx/s +14.0%

Load Testing Results (parallel-execution)

Scenario tx/s
1 parallel 228.08
2 parallel 352.50
5 parallel 436.87
10 parallel 459.95
20 parallel 442.76
2 contention 195.86
5 contention 194.02
2 acct_sets 145.99
5 acct_sets 177.38

Note: Performance results may vary based on system resources and database state.

Last updated by commit 9817393

@bodymindarts
bodymindarts merged commit 973c520 into main Sep 16, 2026
6 checks passed
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.

1 participant