You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Experimental follow-up to #81000. That merged change fixes the filed #80624 concurrent-create loss by recovering unexpected on-disk job IDs. This branch explores a stronger conflict-aware jobs.json contract:
bind each in-lock load_jobs() result to its loaded base
reconcile base/desired/current snapshots for disjoint creates, edits, and deletes
use a short .jobs.commit.lock around final reconciliation and atomic publication when supported
bound generation retries instead of doing an unchecked terminal write
keep the new lock file out of backup/import
Why this is draft
The implementation is correctness-reviewed and test-green, but it is substantially larger than the demonstrated production incident: roughly 407 net production lines plus 407 test lines. #81000 already fixed the reported concurrent-create failure. The remaining motivation is a stronger same-ID/degraded-writer storage guarantee, for which there is not currently a linked Hermes production report.
This should not merge as a routine small bugfix. Keep it draft until maintainers explicitly want the stronger storage-semantics contract and agree that its complexity is justified. If that contract is not desired, this PR should be closed rather than partially trimmed into a lock-only or generation-only patch that would not deliver the claimed invariant.
Availability policy
The broad .jobs.lock deliberately degrades to process-local protection when its backend is unavailable or a sibling is wedged (#60703/#60855). The short publication lock follows the same policy: missing backends, unsupported lock operations, lock-file preparation failures, or timeout log a warning and continue with the process lock, three-way reconciliation, and bounded generation checks.
When the short lock is available it closes the final generation-check-to-replace window for cooperating Hermes writers. In degraded mode that small final window remains. This preserves Hermes' established scheduler-availability tradeoff.
Deliberate boundaries
this is best-effort conflict hardening, not a due-job dispatch CAS
legacy/manual writers that ignore Hermes locks remain outside the cooperating-writer guarantee
no hardlink/inode/path-swap framework is introduced
Refreshed against main@222465d84. The cron/jobs.py conflict was resolved by retaining this PR’s bounded, fail-closed publication retry while preserving current main’s JSON serialization change. Current validation: the full tests/cron directory plus backup regressions passed (585 passed, 0 failed, 1 Windows-only skip); Ruff and git diff --check pass.
Independent and adversarial audit found a real degraded-publication gap: if the short commit lock was missing or unsupported, two writers could both pass the generation check and race the final replace (including replace=True). The new head now fails closed before publication in that state. Regressions cover no backend plus ENOSYS/ENOTSUP/EOPNOTSUPP, both replace modes, unchanged bytes, and no temp publication. Final validation: 593 passed, 1 Windows-only skip; final reviews found no remaining P0–P3 issue.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
comp/cronCron scheduler and job managementP2Medium — degraded but workaround existstype/bugSomething isn't working
2 participants
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Experimental follow-up to #81000. That merged change fixes the filed #80624 concurrent-create loss by recovering unexpected on-disk job IDs. This branch explores a stronger conflict-aware
jobs.jsoncontract:load_jobs()result to its loaded base.jobs.commit.lockaround final reconciliation and atomic publication when supportedWhy this is draft
The implementation is correctness-reviewed and test-green, but it is substantially larger than the demonstrated production incident: roughly 407 net production lines plus 407 test lines. #81000 already fixed the reported concurrent-create failure. The remaining motivation is a stronger same-ID/degraded-writer storage guarantee, for which there is not currently a linked Hermes production report.
This should not merge as a routine small bugfix. Keep it draft until maintainers explicitly want the stronger storage-semantics contract and agree that its complexity is justified. If that contract is not desired, this PR should be closed rather than partially trimmed into a lock-only or generation-only patch that would not deliver the claimed invariant.
Availability policy
The broad
.jobs.lockdeliberately degrades to process-local protection when its backend is unavailable or a sibling is wedged (#60703/#60855). The short publication lock follows the same policy: missing backends, unsupported lock operations, lock-file preparation failures, or timeout log a warning and continue with the process lock, three-way reconciliation, and bounded generation checks.When the short lock is available it closes the final generation-check-to-replace window for cooperating Hermes writers. In degraded mode that small final window remains. This preserves Hermes' established scheduler-availability tradeoff.
Deliberate boundaries
Validation
Refreshed conflict-free against
main@715d26cdfon 2026-08-13.tests/cronplus backup coverage: 582 passed, 0 failedgit diff --check: clean