Skip to content

fix(engine, filesystem-http): reset config watch keys after every event - #2625

Open
akrambek wants to merge 3 commits into
developfrom
claude/engine-config-watch-reset
Open

akrambek wants to merge 3 commits into
developfrom
claude/engine-config-watch-reset

Conversation

@akrambek

@akrambek akrambek commented Sep 30, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #2624

Problem

  • EngineConfigWatchTask.call() loops on watcher.take() and calls onPathChanged(...), but never calls pollEvents() or reset() on the returned key. A signalled WatchKey is not re-queued until it is reset. When an event leaves the config text unchanged, EngineManager.onPathChanged returns early, nothing re-arms the key, and every later config change is ignored until restart.
  • HttpWatchKey (filesystem-http) does not implement reset(): it throws UnsupportedOperationException. So once the watch loop resets keys, http-sourced configs stop reloading after the first change.
  • HttpWatchKey.cancel() throws NullPointerException if the key has not sent its first watch request yet. A reload that unregisters such a key fails, so the new config is rejected.

Change

  • engine: after every take(), drain key.pollEvents(), call onPathChanged(...), then call key.reset(). This happens whether or not the config changed. If reset() reports the config path key is no longer valid, register the config path again.
  • filesystem-http: HttpWatchKey now follows the WatchKey contract.
    • A key is queued once when it is first signalled.
    • reset() re-queues it only if events are still pending, and returns false once the key is cancelled.
    • cancel() works before the first watch request, and a cancelled key sends no further watch requests.

Consumers of HttpWatchService must now call reset() after handling a key, as the WatchKey contract requires. Before this change, a key was queued again on every event.

Tests

  • EngineConfigWatchTaskTest.shouldApplyChangeAfterUnchangedRewrite: rewrite the local config with the same text, then change it; the change is applied.
  • EngineConfigWatchTaskTest.shouldApplyHttpChangesAfterReload: an http-sourced config (local long-poll server with etags) changes twice, and both changes are applied.
  • HttpFileSystemTest.shouldCancelWatchKeyBeforeWatching: cancelling right after register does not throw; the key is invalid and reset() returns false.
  • HttpFileSystemIT.shouldWatch: now calls reset() between the two take() calls and checks that it returns true.

Each new test failed before its fix and passes after it.

馃 Generated with Claude Code

akrambek and others added 2 commits September 30, 2026 23:00
The config watch loop never drained or reset the key returned by take(),
so once an event produced no config change the key was never re-queued
and later edits were ignored until restart. Drain events and reset the
key after each take(), re-registering the config path if the key is no
longer valid.

Fixes #2624

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
HttpWatchKey.reset() threw UnsupportedOperationException, and cancel()
threw NullPointerException when the key had not yet issued its first
watch request. Keys now follow the WatchKey contract: a signalled key is
queued once and re-queued by reset() only when events are pending.
cancel() works at any point and stops further watch requests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@akrambek akrambek changed the title fix(engine): reset config watch key after every event fix(engine, filesystem-http): reset config watch keys after every event Sep 30, 2026
Register the config directory synchronously before writing, then wait
on observed watch callbacks instead of polling with sleeps. Enable
config watch explicitly and use generous timeouts.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@akrambek
akrambek marked this pull request as ready for review October 2, 2026 14:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Engine config watcher stops reloading after a no-op change (WatchKey never reset)

1 participant