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:
@@ -27,6 +27,12 @@ type Service struct {
|
||||
store *storage.Store
|
||||
jobs []domain.Job
|
||||
runtimes map[int]*domain.JobRuntime
|
||||
|
||||
// observers and their guard live in events.go. dispatchMu is separate from mu
|
||||
// so that emitting an event never requires (or is held under) the state lock:
|
||||
// the Service must release mu before dispatching, per the locking contract.
|
||||
dispatchMu sync.Mutex
|
||||
observers []Observer
|
||||
}
|
||||
|
||||
// NewService wires the Service to a loaded store and its jobs. It builds the
|
||||
|
||||
Reference in New Issue
Block a user