T3.2: Add app event types and observer dispatch

Add src/app/events.go: a sealed Event interface with three concrete
types (JobChanged, RunRecorded, SchedulerStateChanged), an Observer
interface plus ObserverFunc adapter, and Subscribe/emit on the Service.
This replaces the scheduler's single onChange callback with typed
events the UI can exhaustively type-switch over.

Dispatch is serialized by a dedicated dispatchMu (separate from the
state lock): observers never run concurrently, emit must be called
without holding s.mu so observers can read Service state, and observers
must not re-enter an emitting method. emit is wired to mutating ops in
T3.3. Adds tests for ordered multi-observer delivery, empty-observer
no-op, and observer-reads-state-without-deadlock.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
mixeme
2026-06-19 07:39:34 +03:00
parent 9931ec1237
commit 5e51381b7a
4 changed files with 157 additions and 1 deletions
+1 -1
View File
@@ -261,7 +261,7 @@ Track progress here. Mark tasks complete as they land and pass review.
### Phase 3 — Application service layer
- [x] T3.1 — Create `src/app/service.go`; owns state behind mutex
- [ ] T3.2 — Add `src/app/events.go`; Event types + Observer
- [x] T3.2 — Add `src/app/events.go`; Event types + Observer
- [ ] T3.3 — Add state-mutating operations to service
- [ ] T3.4 — Convert `scheduler` to use service; inject Clock
- [ ] T3.5 — Move display helpers to `src/app/format.go`