-
Notifications
You must be signed in to change notification settings - Fork 0
Description
Epic: #87 — Architectural Simplification v0.6.0
Goal
Remove ~22 overhead events, replace with direct calls. Keep events only for genuine fan-out (terminal-state handlers) and command triggers.
Sub-tasks
1a. Replace Query Events with Direct Calls
Problem: TaskManager uses eventBus.request(TaskStatusQuery) → QueryHandler → taskRepo.findById(). This adds ~1ms latency per query and exists only for architectural purity.
Change: Inject TaskRepository and OutputCapture into TaskManagerService. Replace request() calls with direct repository calls.
Files:
src/services/task-manager.ts— AddtaskRepo: TaskRepositoryandoutputCapture: OutputCaptureto constructor. Replacerequest(TaskStatusQuery)withtaskRepo.findById(). Replacerequest(TaskLogsQuery)withoutputCapture.getOutput().src/bootstrap.ts— PasstaskRepositoryandoutputCapturetoTaskManagerServiceconstructor.src/core/events/events.ts— RemoveTaskStatusQuery,TaskStatusResponse,TaskLogsQuery,TaskLogsResponseevent types.src/services/handlers/query-handler.ts— Remove entirely (all functionality moved to direct calls).src/services/handler-setup.ts— Remove QueryHandler from standard handlers list.- Tests: Remove query-handler tests, update task-manager tests.
Also: Replace eventBus.request(NextTaskQuery) in WorkerHandler with direct queue.dequeue() call.
src/services/handlers/worker-handler.ts— InjectTaskQueue, callqueue.dequeue()directly.src/core/events/events.ts— RemoveNextTaskQueryevent type.src/services/handlers/queue-handler.ts— RemoveNextTaskQuerysubscription and handler.
1b. Linearize the Trigger Chain
Problem: TaskDelegated → PersistenceHandler.save() → emit TaskPersisted → QueueHandler.enqueue() → emit TaskQueued → WorkerHandler.processNextTask(). This is a strictly sequential pipeline pretending to be event-driven.
Change: TaskManager.delegate() calls taskRepo.save() directly, then calls queue.enqueue() (via a new method or direct call), then triggers worker processing. The TaskDelegated event is still emitted for fan-out subscribers (DependencyHandler needs it).
Files:
src/services/task-manager.ts— After emittingTaskDelegated, calltaskRepo.save(task)directly, thenqueue.enqueue(task)(if not blocked by dependencies).src/services/handlers/persistence-handler.ts— RemoveTaskDelegatedsubscription (TaskManager now saves directly). Keep terminal-state subscriptions (TaskStarted,TaskCompleted,TaskFailed,TaskCancelled,TaskTimeout).src/services/handlers/queue-handler.ts— RemoveTaskPersistedsubscription. Add directenqueueIfReady(task)method callable by TaskManager.src/core/events/events.ts— RemoveTaskPersistedevent type.
Keep: TaskDelegated event (DependencyHandler subscribes), TaskQueued event (WorkerHandler subscribes — or make this a direct call too in 1c).
1c. Remove Informational-Only Events
Problem: OutputCaptured, WorkerSpawned, RecoveryStarted, RecoveryCompleted, SystemResourcesUpdated are consumed only for debug logging or advisory metrics.
Change: Replace with direct logger calls at the point of action. Remove event definitions and subscriptions.
Files:
src/core/events/events.ts— Remove the 5 event types listed above.src/implementations/event-driven-worker-pool.ts— RemoveWorkerSpawnedemission (already logged locally).src/implementations/output-capture.ts— RemoveOutputCapturedemission.src/services/recovery-manager.ts— RemoveRecoveryStarted/RecoveryCompletedemissions (already logged).src/services/handlers/output-handler.ts— Remove entirely (only consumedOutputCapturedfor debug logging).src/services/autoscaling-manager.ts— RemoveSystemResourcesUpdatedsubscription. If AutoscalingManager is advisory-only with no actionable behavior, consider removing it entirely.
1d. Resolve waitForCheckpoint Race Condition
Problem: DependencyHandler and CheckpointHandler both subscribe to TaskCompleted. DependencyHandler needs the checkpoint that CheckpointHandler creates, so it races with a subscription + DB lookup (lines 444-494 in dependency-handler.ts).
Change: With the hybrid model, make checkpoint creation explicit in the completion path. The completion fan-out calls CheckpointHandler.createCheckpoint() first, then DependencyHandler.resolveDependencies(). The race condition disappears.
Files:
src/services/handlers/dependency-handler.ts— RemovewaitForCheckpoint()method and race logic. Accept checkpoint as a parameter or query it after guaranteed creation.
Files Changed
Modified
src/services/task-manager.tssrc/core/events/events.tssrc/services/handlers/worker-handler.tssrc/services/handlers/queue-handler.tssrc/services/handlers/persistence-handler.tssrc/services/handlers/dependency-handler.tssrc/services/handler-setup.tssrc/bootstrap.tssrc/implementations/event-driven-worker-pool.tssrc/implementations/output-capture.tssrc/implementations/resource-monitor.tssrc/services/recovery-manager.ts
Removed
src/services/handlers/query-handler.ts— Replaced by direct repo callssrc/services/handlers/output-handler.ts— Only consumed debug eventsrc/services/autoscaling-manager.ts— Advisory-only, no actionable behaviortests/unit/services/handlers/query-handler.test.tstests/unit/services/handlers/output-handler.test.ts
Risk
Medium — touches core orchestration and task delegation flow. Sub-steps (1a → 1b → 1c → 1d) can be validated incrementally.
Verification
npm run build— clean compilationnpx biome check src/ tests/— no lint issues- All test groups pass: core, handlers, services, repositories, adapters, CLI, integration
- Event audit:
grep -r "emit\|subscribe" src/shows only ~15 retained events