feat(FN-3507): block dispatch when project lacks node mapping
Adds validation to block task dispatch when no project-node mapping exists (FN-3507), including a read helper in CentralCore and a new `node-dispatch-validation` module integrated into the scheduler and in-process runtime, with test coverage across routing and validation scenarios. Fusion-Task-Id: FN-3507
This commit is contained in:
@@ -1039,6 +1039,15 @@ Task dispatch routing is resolved in two layers:
|
||||
|
||||
### Dispatch flow in scheduler
|
||||
|
||||
Within `Scheduler.schedule()` dispatch for `todo` tasks now runs node gates in this order:
|
||||
|
||||
1. `resolveEffectiveNode()` chooses routing source (`task-override`, `project-default`, `local`).
|
||||
2. If a node is selected, `validateNodeDispatch` checks for a persisted `(projectId, nodeId)` working-directory mapping (`CentralCore.getProjectNodePath`).
|
||||
3. Missing/blank mappings block dispatch (task stays in `todo`) and log `Execution blocked: project has no path mapping for node <id>`.
|
||||
4. Only after mapping validation passes does `applyUnavailableNodePolicy()` evaluate node health and optional `fallback-local` behavior.
|
||||
|
||||
This preserves a clear separation between configuration correctness (mapping exists) and runtime health/failover policy.
|
||||
|
||||
### Unavailable-node policy
|
||||
|
||||
`unavailableNodePolicy` is a validated/stored project setting (`block` default, `fallback-local` allowed) and is enforced during scheduler dispatch when both conditions are true:
|
||||
|
||||
@@ -154,7 +154,14 @@ This allows each project to maintain independent routing behavior even when mana
|
||||
|
||||
`unavailableNodePolicy` is project-scoped and can be set differently per project (`block` or `fallback-local`).
|
||||
|
||||
Current behavior: scheduler dispatch records effective node/source for each task, but health-based block/fallback enforcement is not yet applied in the scheduler dispatch path.
|
||||
Dispatch ordering now enforces project/node path mapping validation before health policy evaluation:
|
||||
|
||||
1. Resolve effective node (`Task.nodeId` → `defaultNodeId` → local).
|
||||
2. If routed to a node, require a persisted `projectNodePathMappings` entry for `(projectId, nodeId)`.
|
||||
3. If mapping is missing/blank, dispatch is blocked in `todo` with a clear log message (`Execution blocked: project has no path mapping for node <id>`).
|
||||
4. Only mapped nodes continue to unavailable-node policy (`block` vs `fallback-local`).
|
||||
|
||||
This keeps configuration errors (missing mapping) distinct from health/failover behavior.
|
||||
|
||||
### Example: different node defaults per project
|
||||
|
||||
|
||||
Reference in New Issue
Block a user