Schaerfe Semantik des Statuspfads nach
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
parent
45e7b776ab
commit
1f4fa3d985
6 changed files with 58 additions and 4 deletions
|
|
@ -92,7 +92,12 @@ Noch nicht Teil dieser Stufe:
|
|||
- Admin-UI-Anzeige des letzten Status
|
||||
- Retry-Queue oder lokale Zwischenspeicherung im Agent
|
||||
|
||||
Agent-seitig wird die Server-Erreichbarkeit aktuell lokal als `unknown`, `online` oder `degraded` aus dem Erfolg der HTTP-Reports abgeleitet.
|
||||
Agent-seitig wird die Server-Erreichbarkeit aktuell lokal als `unknown`, `online`, `degraded` oder `offline` aus dem Erfolg der HTTP-Reports abgeleitet.
|
||||
|
||||
Fuer den transportierten Wert im erfolgreichen HTTP-Report gilt aktuell bewusst einfach:
|
||||
|
||||
- wenn ein Report vom Backend akzeptiert wurde, wird dieser Report selbst als `server_connectivity = online` gespeichert
|
||||
- anhaltende Ausfaelle werden primaer ueber lokale Agent-Zustaende und serverseitige `stale`-Ableitung sichtbar
|
||||
|
||||
## Folgeschritte
|
||||
|
||||
|
|
|
|||
|
|
@ -173,10 +173,14 @@ func (a *App) reportStatus(ctx context.Context) {
|
|||
}
|
||||
|
||||
snapshot := a.Snapshot()
|
||||
payloadConnectivity := snapshot.ServerConnectivity
|
||||
if payloadConnectivity == ConnectivityUnknown || payloadConnectivity == ConnectivityOnline || payloadConnectivity == ConnectivityDegraded || payloadConnectivity == ConnectivityOffline {
|
||||
payloadConnectivity = ConnectivityOnline
|
||||
}
|
||||
|
||||
err := a.reporter.Send(ctx, statusreporter.Snapshot{
|
||||
Status: string(snapshot.Status),
|
||||
ServerConnectivity: string(snapshot.ServerConnectivity),
|
||||
ServerConnectivity: string(payloadConnectivity),
|
||||
ScreenID: snapshot.ScreenID,
|
||||
ServerBaseURL: snapshot.ServerBaseURL,
|
||||
MQTTBroker: snapshot.MQTTBroker,
|
||||
|
|
|
|||
|
|
@ -16,10 +16,12 @@ type recordingReporter struct {
|
|||
callCount int
|
||||
err error
|
||||
errs []error
|
||||
snapshots []statusreporter.Snapshot
|
||||
}
|
||||
|
||||
func (r *recordingReporter) Send(_ context.Context, _ statusreporter.Snapshot) error {
|
||||
func (r *recordingReporter) Send(_ context.Context, snapshot statusreporter.Snapshot) error {
|
||||
r.callCount++
|
||||
r.snapshots = append(r.snapshots, snapshot)
|
||||
if len(r.errs) > 0 {
|
||||
err := r.errs[0]
|
||||
r.errs = r.errs[1:]
|
||||
|
|
@ -212,13 +214,14 @@ func TestAppRunReportsStatusWithoutStoppingOnReporterError(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestAppRunMarksServerConnectivityOnlineAfterSuccessfulReport(t *testing.T) {
|
||||
reporter := &recordingReporter{}
|
||||
application := newApp(config.Config{
|
||||
ScreenID: "screen-online",
|
||||
ServerBaseURL: "http://127.0.0.1:8080",
|
||||
MQTTBroker: "tcp://127.0.0.1:1883",
|
||||
HeartbeatEvery: 1,
|
||||
StatusReportEvery: 1,
|
||||
}, log.New(&bytes.Buffer{}, "", 0), time.Now, &recordingReporter{})
|
||||
}, log.New(&bytes.Buffer{}, "", 0), time.Now, reporter)
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
errCh := make(chan error, 1)
|
||||
|
|
@ -239,6 +242,16 @@ func TestAppRunMarksServerConnectivityOnlineAfterSuccessfulReport(t *testing.T)
|
|||
t.Fatalf("ServerConnectivity = %q, want %q", got, want)
|
||||
}
|
||||
|
||||
if reporter.callCount == 0 {
|
||||
cancel()
|
||||
t.Fatal("reporter was not called")
|
||||
}
|
||||
|
||||
if got, want := reporter.snapshots[0].ServerConnectivity, string(ConnectivityOnline); got != want {
|
||||
cancel()
|
||||
t.Fatalf("first reported connectivity = %q, want %q", got, want)
|
||||
}
|
||||
|
||||
cancel()
|
||||
<-errCh
|
||||
}
|
||||
|
|
@ -287,4 +300,8 @@ func TestReportStatusRecoversFromOfflineToOnline(t *testing.T) {
|
|||
if got, want := application.Snapshot().ServerConnectivity, ConnectivityOnline; got != want {
|
||||
t.Fatalf("recovered state = %q, want %q", got, want)
|
||||
}
|
||||
|
||||
if got, want := reporter.snapshots[len(reporter.snapshots)-1].ServerConnectivity, string(ConnectivityOnline); got != want {
|
||||
t.Fatalf("recovery payload connectivity = %q, want %q", got, want)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,6 +25,11 @@ func handleMeta(w http.ResponseWriter, _ *http.Request) {
|
|||
"method": http.MethodGet,
|
||||
"path": "/api/v1/screens/{screenId}/status",
|
||||
},
|
||||
{
|
||||
"name": "player-status-ingest",
|
||||
"method": http.MethodPost,
|
||||
"path": "/api/v1/player/status",
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ func handlePlayerStatus(store playerStatusStore) http.HandlerFunc {
|
|||
writeError(w, http.StatusBadRequest, "screen_id_required", "screen_id ist erforderlich", nil)
|
||||
return
|
||||
}
|
||||
request.ScreenID = strings.TrimSpace(request.ScreenID)
|
||||
|
||||
if strings.TrimSpace(request.Timestamp) == "" {
|
||||
writeError(w, http.StatusBadRequest, "timestamp_required", "ts ist erforderlich", nil)
|
||||
|
|
|
|||
|
|
@ -90,6 +90,28 @@ func TestHandlePlayerStatusRejectsMissingScreenID(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestHandlePlayerStatusStoresNormalizedScreenID(t *testing.T) {
|
||||
store := newInMemoryPlayerStatusStore()
|
||||
body := []byte(`{
|
||||
"screen_id": " info01-dev ",
|
||||
"ts": "2026-03-22T16:00:00Z",
|
||||
"status": "running"
|
||||
}`)
|
||||
|
||||
req := httptest.NewRequest(http.MethodPost, "/api/v1/player/status", bytes.NewReader(body))
|
||||
w := httptest.NewRecorder()
|
||||
|
||||
handlePlayerStatus(store)(w, req)
|
||||
|
||||
if got, want := w.Code, http.StatusOK; got != want {
|
||||
t.Fatalf("status = %d, want %d", got, want)
|
||||
}
|
||||
|
||||
if _, ok := store.Get("info01-dev"); !ok {
|
||||
t.Fatal("store.Get(normalized) ok = false, want true")
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandlePlayerStatusRejectsMissingTimestamp(t *testing.T) {
|
||||
body := []byte(`{
|
||||
"screen_id": "info01-dev",
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue