Repository navigation
fix: add 30s timeout to SQLite semaphore to prevent deadlock hangs - #31461
HrushiYadav wants to merge 1 commit into
Conversation
Backport of anomalyco#31461 (by @HrushiYadav). Ported timeoutFail -> timeoutOrElse({orElse: () => Effect.fail(...)}) because [email protected] has no timeoutFail. An indefinite semaphore wait could deadlock the whole DB layer; now it fails with a SqlError after 30s instead of hanging. Co-Authored-By: Claude Mythos 5 <[email protected]>
The in-process Semaphore(1) guarding the single SQLite connection has no timeout, so any deadlock or re-entrant lock attempt causes the process to hang forever with no error. Add a 30s timeout to both the regular query acquirer and the transaction acquirer so contention surfaces as a clear SqlError instead of a silent futex hang. Closes #29395
5170cbf to
93cbb9b
Compare
|
Friendly ping -- this adds a 30s timeout to the SQLite semaphore to prevent deadlock hangs. Any feedback or changes needed? |
|
Automated PR Cleanup Thank you for contributing to opencode. Due to the high volume of PRs from users and AI agents, we periodically close older PRs using automated criteria so maintainers can focus review time on the most active and community-supported contributions. This PR was closed because it matched the following cleanup criteria:
PRs created within the last month are not affected by this cleanup. If you believe this PR was closed incorrectly, or if you are still actively working on it, please leave a comment explaining why it should be reopened. A maintainer can review and reopen it if appropriate. Thanks again for taking the time to contribute. |
Issue for this PR
Closes #29395
Type of change
What does this PR do?
The in-process
Semaphore(1)guarding the single SQLite connection insqlite.bun.tsblocks forever when the permit can't be acquired (deadlock, re-entrant lock, or concurrent instance contention). This adds a 30-secondEffect.timeoutFailto both the regular query acquirer and the transaction acquirer so the hang surfaces as a clearSqlErrorinstead of a silent futex wait with no timeout, no error, and no progress.How did you verify your code works?
InstanceStore.load->boot->fromDirectory->bootstrap.run) and confirmed both theacquirerandtransactionAcquirerare the only JS-level serialization points for SQLite accessEffect.timeoutFailcorrectly interacts withsemaphore.withPermits(timeout fires interruption, permit is not acquired, no leak)Effect.timeoutFailworks insideEffect.uninterruptibleMask+restore(...)(the restore region makessemaphore.takeinterruptible so the timeout signal can reach it)SqlErrorwithclassifySqliteErrormatches the existing error handling pathScreenshots / recordings
N/A (backend change)
Checklist