Skip to content

fix(service-manager): clear pending action when start, stop or assemble throws - #12

Open
Kshot3000 wants to merge 1 commit into
rosen-bridge:devfrom
Kshot3000:fix/service-action-retry-after-failure
Open

Kshot3000 wants to merge 1 commit into
rosen-bridge:devfrom
Kshot3000:fix/service-action-retry-after-failure

Conversation

@Kshot3000

Copy link
Copy Markdown

Fixes #10.

Problem

In AbstractService, the success branch of startService / stopService / assembleService clears actionPromise, but the .catch branch only releases the semaphore. After one start() that throws, actionPromise keeps pointing at the rejected promise: the first call returns false, but every later call takes the "already an active request" branch and returns that old rejection — start() never runs again. stop and assemble behave the same way. A service that throws once (e.g. the database was not reachable yet) can never be started again without restarting the process, and ServiceManager.watch() retries hit the same unhandled rejection.

Fix

Clear this.actionPromise = undefined in the catch branches of all three methods, mirroring the success path. One line each; no behavior change for in-flight deduplication or for actions that return false without throwing (that path already cleared the promise).

Tests

New tests/abstractService.spec.ts with a service whose start/stop/assemble throw on the first attempt and succeed on the second:

  • all 3 tests fail on the current code — the second call returns the old rejected promise (promise rejected "Error: start failed" instead of resolving)
  • all 3 pass with the fix, and the attempt counters confirm the action actually ran again

Full package suite: 18/18 pass (15 existing + 3 new). tsc --noEmit clean, eslint/prettier clean. Changeset included (@rosen-bridge/service-manager: patch).

…le throws

AbstractService only cleared actionPromise on success. When start(),
stop() or assemble() threw, the catch branch released the semaphore
but left actionPromise pointing at the rejected promise, so every
later startService/stopService/assembleService call returned that old
rejection and the action never ran again — a service that failed once
(e.g. database not reachable yet) could not be recovered without a
process restart, and ServiceManager.watch() retries hit the same
rejection unhandled.

Clear actionPromise in the catch branches too, mirroring the success
path. Adds tests covering the retry of all three actions after a
throwing first attempt.
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.

A Failed Service Start Blocks Every Retry

1 participant