Repository navigation
fix: release the id increment lock after generation - #87
Conversation
- the success path of DataAdapter._id leaked the RLock acquisition, deadlocking inserts from background threads (scheduler jobs) on non Mongo adapters - regression test asserts the lock is acquirable from another thread
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (3)
📝 WalkthroughWalkthroughChangesIdentifier lock fix
Poem
✨ Finishing Touches📝 Generate docstrings
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 |
|
Bugbot is not enabled for your account, so this pull request was not reviewed. Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs. |
There was a problem hiding this comment.
Pull request overview
Fixes a concurrency deadlock in DataAdapter._id where the increment lock (_inc_lock, an RLock) was not released on the success path, causing background threads (e.g., scheduler jobs using TinyAdapter) to block indefinitely when generating identifiers.
Changes:
- Release
_inc_lockin afinallyblock to guarantee unlocking after identifier increment inDataAdapter._id. - Add a regression test to ensure
_inc_lockcan be acquired from another thread after_idcompletes. - Document the fix in
CHANGELOG.mdunder Unreleased > Fixed.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| src/appier/data.py | Ensures _inc_lock is always released after _id updates the increment value. |
| src/appier/test/data.py | Adds a multithreaded regression test validating the lock is not leaked after _id. |
| CHANGELOG.md | Records the deadlock fix in the Unreleased “Fixed” section. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
DataAdapter._idacquired_inc_lock(anRLock) and released it only on the exception path, leaking the acquisition on every successful call. The owning thread (whichever performs the first insert, typically the main thread at boot) keeps re-entering its ownRLock, so single-threaded usage never notices - but any other thread blocks forever on its first insert through an adapter that generates identifiers via_id(e.g.TinyAdapter). In practice, appierScheduler-driven jobs writing over the tiny adapter deadlock silently: the tick never completes and nothing is logged.The lock is now released in a
finallyclause. The newtest_id_lock_releaseregression test asserts the lock is acquirable from another thread after_idruns - it fails on the previous code and passes now. The Mongo path was never affected (identifier generation is delegated to pymongo).Found while wiring fidelia's scheduler bots (hivesolutions/fidelia#5), whose thread hung on the first
Voucher.save().Closes #86