Repository navigation
fix: preserve interval schedule on re-registration - #27
Merged
Merged
Conversation
…16 pins SKILL.md describes 6.x; a project pinned to josk@5.0.0 (the last Node 14/16 release) was being handed PostgresAdapter, pause()/resume(), concurrency, execute and lockLeaseTime, and the v6 'default' prefix, none of which apply there. A short version gate at the top of SKILL.md routes such projects to references/legacy-v5.md, read only behind that gate: the 3.x–5.x ladder, 5.0.0 exports/options/defaults, the ready() handler contract (sync zero-arg handlers are never rescheduled), the '' vs 'default' prefix change, and the Redis 4→5 key layout. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017C1PrDpdMoybvFaAWvzktR
…rs it JoSk#setInterval() calls adapter.add() on every call, and every adapter's add() reset the task's next run to now + delay. Each process re-registers its intervals on boot, so every boot of any instance pushed every interval back by a full delay for the whole cluster. A crash-looping instance, frequent rolling deploys, or dev hot reloads starved intervals: a 10-minute Mongo-backed interval went 70 minutes without running after five reloads. add() now keeps the stored next run when the task already exists, is not deleted, is an interval, has the same delay, and the stored time is earlier than now + delay. A past-due task stays past-due and runs on the first revolution after boot; the atomic claim still lets only one instance run it. New tasks, deleted tasks, a changed delay, a changed kind, and every setTimeout/setImmediate registration still schedule at now + delay. A later stored time (e.g. a zombie park) is replaced by now + delay, so no run is ever scheduled later than before. Each adapter decides in one atomic statement: - MongoAdapter: upsert through an update pipeline with $cond (uid and delay wrapped in $literal). setTimeout keeps the plain $set upsert. Pipeline updates need mongod 4.2+; README already requires 4.4+. - RedisAdapter: ADD_TASK_SCRIPT decides in Lua and writes the same value to the task hash and the schedule ZSET. It still refuses to revive a tombstoned (isDeleted) entry, as before. - PostgresAdapter: INSERT ... ON CONFLICT DO UPDATE with a CASE on execute_at. The fix is on by default: the old reset is a bug for any multi-instance or often-restarted deployment. To restart the countdown on purpose, change delay or clear the task before setInterval(). Tests: Jest unit checks of the add() statement per adapter; live contract tests for all three adapters (keep earlier, past-due stays due and gets claimed, later time replaced, changed delay, deleted task, setTimeout and kind change, $-prefixed uid); mocha restart tests per adapter (first instance dies, second instance re-registers). Docs: README setInterval section, adapter contract, blank-example, skill references. index.cjs and .d.ts regenerated via prepublishOnly. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014t7uCinRDEGFWJcVwtk3Uh
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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
executeAtwhen an active interval is re-registered with the same delay. Restarts no longer postpone cluster-wide work by a full interval; past-due tasks run after the next scheduler revolution.6.4.0.CI coverage
The interval restart integration tests are registered in the Redis, MongoDB, and PostgreSQL Mocha suites. The existing GitHub Actions driver-version and server-version matrices run
npm run test:redis,npm run test:mongo, andnpm run test:postgres, so all six adapter matrices execute the new restart tests.Verification
npm run test:coverage: 107 passed, 39 live tests skipped because no test-store URLs were configured.npm run test:bun: 107 passed.npm run test:adapter-guards: 6 passed.npm run test:types: passed.npm run prepublishOnly: passed.npm pack --dry-run: reportsjosk@6.4.0.The live Redis, MongoDB, and PostgreSQL suites were not run locally to avoid touching shared dev services. CI runs them against isolated services.