Skip to content

Release path: rollback only; throttle prunes; gate exit gc; 5s timeout sweep - #17

Merged
adhikjoshi merged 1 commit into
mainfrom
perf/release-path-and-prune
Aug 20, 2026
Merged

Release path: rollback only; throttle prunes; gate exit gc; 5s timeout sweep#17
adhikjoshi merged 1 commit into
mainfrom
perf/release-path-and-prune

Conversation

@adhikjoshi

@adhikjoshi adhikjoshi commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Four production findings from the profiler/DB audit, one PR:

  1. 45 SET-pairs/s eliminated. resetConnection() re-issued SET ISOLATION + SET autocommit on every release; neither can change during a request (autocommit is never touched by transactions — START TRANSACTION suspends it without writing the variable). Release now only rolls back. normalizeSession() covers the two genuinely-new-session moments — creation and the reconnector's PDO swap (the latter was a real gap: a reconnected session ran at server defaults). One round trip on MySQL; MariaDB <11.1 lacks transaction_isolation (MDEV-21921) so that driver keeps the standard-SQL form — verified against MariaDB 10.11/11.4 + MySQL 8.0 in review.
  2. One process-global gc_collect_cycles per DB request removed. The coroutine-exit defer now returns early when the coroutine holds no pooled connections.
  3. Prune throttled to once per second (checkout/release/worker all pruned before — up to 3 full channel drain-refills per request, and a drain parks idle connections where a concurrent checkout can't see them). Checkout at max now heals vanished borrowers via reconcile before concluding the pool is exhausted (review catch — the throttle would otherwise have opened a false-exhaustion window).
  4. Timeout sweep 1s → 5s (config octane.swoole.timeout_sweep_interval_ms, clamped ≥1000): ≤5s overrun on 120–240s budgets.

E2E on a real Swoole server vs local MySQL: 213 → 10 SET statements per 100 requests (−95%), 100/100 success. Suite: 179 green; five mutation tests pin the guards. Adversarially reviewed; its MariaDB, false-exhaustion, clamp, and comment findings are all incorporated.

🤖 Generated with Claude Code


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

Production still showed 45 SET-pairs/s: resetConnection() re-issued
SET SESSION TRANSACTION ISOLATION + SET autocommit on every release,
though nothing in a request can change either - transactions restore
autocommit themselves, and the isolation level only needs setting when
a server session is genuinely new. Release now only rolls back;
normalizeSession() covers the two real new-session moments (creation
and the reconnector's PDO swap - the latter was a gap), and does it in
one round trip instead of two.

The coroutine-exit defer ran a process-global gc_collect_cycles before
every release walk; the roots buffer is almost never empty under load,
so this was a full cycle-collection per DB request even when the Worker
had already released everything. It now returns early when the
coroutine holds no pooled connections.

pruneIdleConnections() ran up to three times per request (checkout,
release, worker sweep), each paying a weakref reconcile plus a full
channel drain-and-refill - and a concurrent checkout that yields into
the drained channel creates a connection it never needed. Opportunistic
prunes are now throttled to once per prune_interval (default 1s); the
heartbeat stays the primary pruner. Checkout also skips the 1ms
channel pop when nothing is pooled.

The request-timeout sweep ticked every 1s over the whole timer table;
it now defaults to 5s (octane.swoole.timeout_sweep_interval_ms),
costing at most 5s of timeout precision on 120-240s budgets.
@adhikjoshi
adhikjoshi merged commit c2ba719 into main Aug 20, 2026
2 checks passed
@adhikjoshi
adhikjoshi deleted the perf/release-path-and-prune branch August 20, 2026 18:49
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