feat(process): emit daemon started discovery events

Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
Virgil 2026-04-04 06:12:49 +00:00
parent 040500f3e1
commit 9b3dd1ec49
2 changed files with 58 additions and 0 deletions

View file

@ -275,6 +275,9 @@ func (p *ProcessProvider) listDaemons(c *gin.Context) {
if entries == nil {
entries = []process.DaemonEntry{}
}
for _, entry := range entries {
p.emitEvent("process.daemon.started", daemonEventPayload(entry))
}
c.JSON(http.StatusOK, api.OK(entries))
}
@ -287,6 +290,7 @@ func (p *ProcessProvider) getDaemon(c *gin.Context) {
c.JSON(http.StatusNotFound, api.Fail("not_found", "daemon not found or not running"))
return
}
p.emitEvent("process.daemon.started", daemonEventPayload(*entry))
c.JSON(http.StatusOK, api.OK(entry))
}
@ -503,6 +507,18 @@ func (p *ProcessProvider) emitEvent(channel string, data any) {
_ = p.hub.SendToChannel(channel, msg)
}
func daemonEventPayload(entry process.DaemonEntry) map[string]any {
return map[string]any{
"code": entry.Code,
"daemon": entry.Daemon,
"pid": entry.PID,
"health": entry.Health,
"project": entry.Project,
"binary": entry.Binary,
"started": entry.Started,
}
}
// PIDAlive checks whether a PID is still running. Exported for use by
// consumers that need to verify daemon liveness outside the REST API.
func PIDAlive(pid int) bool {

View file

@ -87,6 +87,48 @@ func TestProcessProvider_ListDaemons_Good(t *testing.T) {
assert.True(t, resp.Success)
}
func TestProcessProvider_ListDaemons_BroadcastsStarted_Good(t *testing.T) {
dir := t.TempDir()
registry := newTestRegistry(dir)
require.NoError(t, registry.Register(process.DaemonEntry{
Code: "test",
Daemon: "serve",
PID: os.Getpid(),
}))
hub := corews.NewHub()
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
go hub.Run(ctx)
p := processapi.NewProvider(registry, nil, hub)
server := httptest.NewServer(hub.Handler())
defer server.Close()
conn := connectWS(t, server.URL)
defer conn.Close()
require.Eventually(t, func() bool {
return hub.ClientCount() == 1
}, time.Second, 10*time.Millisecond)
r := setupRouter(p)
w := httptest.NewRecorder()
req, _ := http.NewRequest("GET", "/api/process/daemons", nil)
r.ServeHTTP(w, req)
assert.Equal(t, http.StatusOK, w.Code)
events := readWSEvents(t, conn, "process.daemon.started")
started := events["process.daemon.started"]
require.NotNil(t, started)
startedData := started.Data.(map[string]any)
assert.Equal(t, "test", startedData["code"])
assert.Equal(t, "serve", startedData["daemon"])
assert.Equal(t, float64(os.Getpid()), startedData["pid"])
}
func TestProcessProvider_GetDaemon_Bad(t *testing.T) {
dir := t.TempDir()
registry := newTestRegistry(dir)