feat(dvm): dispatch pending DVM jobs to worker processes - #734
Conversation
Signed-off-by: Priyanshubhartistm <bhartipriyanshustm@gmail.com>
🦋 Changeset detectedLatest commit: c90c01e The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
There was a problem hiding this comment.
Pull request overview
Adds the missing “dispatch” stage for NIP-90 DVM jobs: polling persisted submitted jobs, sending them to long-lived worker processes over stdin/stdout as newline-delimited JSON, and publishing signed kind 6000–6999 result events back through the relay.
Changes:
- Introduces
spawnWorkerProcess()for persistent NDJSON IPC with worker processes (stdin/stdout multiplexing). - Extends
DvmOrchestratorWorkerto poll/assign jobs, manage in-flight tracking + timeouts, and publish result events. - Extends
DvmJobRepository.findPendingJobs()to optionally filter bykinds, and adds/updates unit tests for the new dispatch flow.
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| test/unit/repositories/dvm-job-repository.spec.ts | Updates pending-job tests for new kinds filter parameter and adds filter coverage. |
| test/unit/cli/process.spec.ts | Adds unit tests for spawnWorkerProcess() NDJSON framing and spawn error classification. |
| test/unit/app/dvm-orchestrator-worker.spec.ts | Adds unit tests for dispatch lifecycle: assign race, missing source event, success publish, timeout, crash, respawn, and reentrancy guard. |
| src/repositories/dvm-job-repository.ts | Adds optional kinds filtering to pending-job query. |
| src/factories/dvm-orchestrator-worker-factory.ts | Wires DB clients + repositories into DvmOrchestratorWorker. |
| src/constants/base.ts | Adds DVM job result kind range constants (6000–6999). |
| src/cli/utils/process.ts | Adds spawnWorkerProcess() helper for long-lived worker IPC over NDJSON. |
| src/app/dvm-orchestrator-worker.ts | Implements dispatch loop, worker lifecycle handling, timeouts, and result event publishing. |
| src/@types/repositories.ts | Updates IDvmJobRepository.findPendingJobs() signature to accept optional kinds. |
| .changeset/dvm-job-dispatch.md | Declares a minor release for DVM job dispatch + result publishing. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Signed-off-by: Priyanshubhartistm <bhartipriyanshustm@gmail.com>
Signed-off-by: Priyanshubhartistm <bhartipriyanshustm@gmail.com>
Uh oh!
There was an error while loading. Please reload this page.
Signed-off-by: Priyanshubhartistm <bhartipriyanshustm@gmail.com>
Uh oh!
There was an error while loading. Please reload this page.
Description
Adds dispatch for pending NIP-90 DVM job requests.
DvmOrchestratorWorkernow spawns one long-livedworker process per configured
dvm.workers[i]entry and multiplexes every in-flight job over that process's stdin/stdout as newline-delimited JSON:DvmJobRepository.findPendingJobs()every 2s and assigns a job via the existing atomicassignWorker().{ id, content }reply back to the pending job by id.timed_outand kills the worker process (any other jobs still in flight on it fail as a side effect; the worker is respawned lazily on the next poll tick).completedand publishes a kind 6000-6999 result event, signed by the relay's own derived keypair (same self-signing pattern already used for invoice notifications inpayments-service.tsdvm.workers[]has no per-worker signing key).failed.spawnWorkerProcess()is a new helper (inprocess.ts) for this a persistent-process counterpart to the existing one-shotrunCommand/runCommandWithOutput(same spawn/error classification conventions:not found/permission-denied/spawn-error), framing messages both ways as newline-delimited JSON since the one-shot helpers buffer all output into a single string, which doesn't work once more than one job can be in flight against the same worker at a time.Related Issue
Part of #639. Closes#731.
Motivation and Context
Job requests (#729) and job persistence (#727) exist, but nothing hands a
submittedjob off to a worker process yet. This is the last piece of Month 1's core job-routing pipeline (worker registry → persistence → ingestion → dispatch).