Release: ORM pool self-heal + coroutine-safety + One Way P2#39
Release: ORM pool self-heal + coroutine-safety + One Way P2#39syntaxwanderer wants to merge 2 commits into
Conversation
A wrong pool-selection guess at boot (SingleConnectionPool cached before SWOOLE_HOOK_ALL is applied) would hand the same hooked PDO socket to two coroutines under load, raising the uncatchable C-level "Socket already bound to another coroutine" fatal that kills the worker. pop() now tracks the owning coroutine; if the cached connection is still bound to a different, live coroutine it mints a dedicated short-lived connection instead of double-binding. The hot CLI path (getCid() < 0) is unchanged and guarded by class_exists for no-Swoole hosts. push() drops a foreign connection rather than overwriting the cached one and releases ownership. Defense-in-depth: the worker degrades to an extra connection instead of crashing. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
getPool() cached the pool-selection decision for the worker's life, so a SingleConnectionPool chosen before the coroutine runtime was live (master-side warmup before fork) was frozen in — degrading every request on that worker with no true pooling. Extract the gate into shouldUseCoroutinePool() and add ensureCoroutineSafePool(), called from getPool()/getAdapter(): once hooks are live, a stale SingleConnectionPool is closed and rebuilt as the coroutine-safe ConnectionPool, and the 7 memoized fields that captured the old pool/adapter (adapter, schemaComparator, syncEngine, transactionManager, seedRunner, resourceModelRelationLoader, aggregateWriteEngine) are invalidated so they rebuild over it. Guarded by TransactionManager::isActive() so the pool is never yanked out from under an open transaction. PoolSelfHealTest exercises the upgrade under real Swoole hook toggling. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (4)
📝 WalkthroughWalkthrough
ChangesSwoole Coroutine-Safe Connection Pool
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2db95cb6bd
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| $this->adapter = null; | ||
| $this->schemaComparator = null; | ||
| $this->syncEngine = null; | ||
| $this->transactionManager = null; |
There was a problem hiding this comment.
Re-check before returning cached transaction managers
This invalidation only happens after ensureCoroutineSafePool() is entered via getPool() or getAdapter(), but getTransactionManager() returns an already memoized TransactionManager without performing that check. In a worker that warms ConnectionRegistry::transactionManagerFor() before Swoole hooks are enabled, a later request that enters through the same transaction path will keep using the old SingleConnectionPool and old adapter, so the self-heal never runs for transactions under coroutine load. Add the same pre-return recheck there, while preserving the active-transaction guard.
Useful? React with 👍 / 👎.
Merges the current
developbatch (9 commits) intomasterfor release. The headline work is closing out the SingleConnectionPool coroutine-crash class of bug; the rest is the accumulated develop backlog.Pool coroutine-safety (this session)
f0232b0guard SingleConnectionPool against cross-coroutine double-bind —pop()tracks the owning coroutine and mints a dedicated short-lived connection instead of double-binding a hooked PDO socket, converting an uncatchable"Socket already bound to another coroutine"worker fatal into graceful degradation.2db95cbself-heal cached pool selection in OrmManager — aSingleConnectionPoolcached beforeSWOOLE_HOOK_ALLis applied now upgrades to the coroutine-safeConnectionPoolonce hooks are live (ensureCoroutineSafePool()), invalidating the 7 memoized fields that captured the stale pool/adapter; guarded byTransactionManager::isActive().Together these are defense-in-depth: the tripwire guarantees "never crash", the self-heal restores "real pooling once the runtime is up". Builds on
73c47e4(gate onRuntime::getHookFlags()), also in this batch.Also in this batch
aac631cCollectionQueryCompiler +whereAnyLikeOR-group (One Way P2)73c47e4pick coroutine-safe pool under a running Swoole server9f849b3/f4779a4/77c6680Track R — ORM event dispatch (ResourceChangedEvent from AggregateWriteEngine + default-dispatcher resolver)93090fe#[ResourceKey]attribute +ResourceMetadata::getResourceKey()06d98adremove obsolete semver release metadataVerification
ai:verifyclean on both pool changes (6/6, 5/5).packages/semitexa-ormConnection + Adapter suites: 25/25 green, incl.PoolSelfHealTest(4 tests, exercises the upgrade under real Swoole hook toggling) andSingleConnectionPoolTest.🤖 Generated with Claude Code
Summary by CodeRabbit
Bug Fixes
Improvements
Tests