package main import ( "encoding/json" "net/http" "sync" "time" "git.cin.su/m/Assistant/runtime/health" ) type workerStatus struct { mu sync.RWMutex workerID string once bool startedAt time.Time lastCycleAt time.Time lastCompleted time.Time lastResult string lastError string } func newWorkerStatus(workerID string, once bool) *workerStatus { return &workerStatus{workerID: workerID, once: once, startedAt: time.Now().UTC()} } func (s *workerStatus) cycleStarted(at time.Time) { s.mu.Lock() defer s.mu.Unlock() s.lastCycleAt = at.UTC() s.lastResult = "running" s.lastError = "" } func (s *workerStatus) cycleFinished(at time.Time, result string) { s.mu.Lock() defer s.mu.Unlock() s.lastCompleted = at.UTC() s.lastResult = result s.lastError = "" } func (s *workerStatus) cycleFailed(at time.Time, err error) { s.mu.Lock() defer s.mu.Unlock() s.lastCompleted = at.UTC() s.lastResult = "failed" s.lastError = err.Error() } func (s *workerStatus) handler() http.Handler { mux := http.NewServeMux() mux.Handle("/healthz", health.Handler{Runtime: "reflection-worker", SemanticGeneration: 1, ArchitectureGeneration: 1}) mux.HandleFunc("/status", func(w http.ResponseWriter, _ *http.Request) { s.mu.RLock() response := struct { Runtime string `json:"runtime"` WorkerID string `json:"worker_id"` Mode string `json:"mode"` StartedAt time.Time `json:"started_at"` LastCycleAt time.Time `json:"last_cycle_at,omitempty"` LastCompleted time.Time `json:"last_completed_at,omitempty"` LastResult string `json:"last_result"` LastError string `json:"last_error,omitempty"` }{Runtime: "reflection-worker", WorkerID: s.workerID, Mode: "durable-reflection-loop", StartedAt: s.startedAt, LastCycleAt: s.lastCycleAt, LastCompleted: s.lastCompleted, LastResult: s.lastResult, LastError: s.lastError} if s.once { response.Mode = "durable-reflection-once" } s.mu.RUnlock() w.Header().Set("Content-Type", "application/json") _ = json.NewEncoder(w).Encode(response) }) return mux }