chore: auto-commit (5 archivos)

- handlers.go
- handlers_test.go
- main.go
- datafactory_events.go
- handlers_datafactory.go

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Egutierrez
2026-05-16 16:33:25 +02:00
parent 8a71839520
commit 11c986edc7
5 changed files with 665 additions and 16 deletions
+57 -8
View File
@@ -2,12 +2,15 @@ package main
import (
"context"
"database/sql"
"encoding/json"
"fmt"
"net/http"
"strings"
"sync"
"time"
"fn-registry/apps/data_factory/datafactory"
"fn-registry/functions/infra"
)
@@ -18,14 +21,48 @@ type Server struct {
pool *DBPool
registryRoot string // raiz del fn_registry (para exec fn ...)
hub *CallMonitorHub
dfHub *DataFactoryHub
// data_factory.db (RW) is opened lazily on first request and reused.
dfPath string
dfMigrationsDir string
dfMu sync.Mutex
dfDB *sql.DB
dfErr error // sticky if a previous open failed
}
func NewServer(pool *DBPool, registryRoot string) *Server {
return &Server{
pool: pool,
registryRoot: registryRoot,
hub: NewCallMonitorHub(pool),
func NewServer(pool *DBPool, registryRoot, dfPath, dfMigrationsDir string) *Server {
s := &Server{
pool: pool,
registryRoot: registryRoot,
hub: NewCallMonitorHub(pool),
dfPath: dfPath,
dfMigrationsDir: dfMigrationsDir,
}
s.dfHub = NewDataFactoryHub(s.dataFactoryDB)
return s
}
// dataFactoryDB returns a RW connection to data_factory.db, lazy-opened on
// first call. Subsequent calls return the cached connection. If the open
// fails it is cached as a sticky error to avoid retry storms; retry after
// process restart.
func (s *Server) dataFactoryDB() (*sql.DB, error) {
s.dfMu.Lock()
defer s.dfMu.Unlock()
if s.dfDB != nil {
return s.dfDB, nil
}
if s.dfErr != nil {
return nil, s.dfErr
}
db, err := datafactory.Open(s.dfPath, s.dfMigrationsDir)
if err != nil {
s.dfErr = err
return nil, err
}
s.dfDB = db
return db, nil
}
// Routes registers all API routes on the given mux.
@@ -50,6 +87,13 @@ func (s *Server) Routes(mux *http.ServeMux) {
// Issue 0086: WebSocket live stream de ops:call_monitor (calls table).
// Hub global con ticker bajo demanda (solo corre con >=1 subscriber).
mux.HandleFunc("GET /api/events/call_monitor", s.handleEvents(s.hub))
// Issue 0097: data_factory.db (nodes, runs, databases).
// REST read-only + WS live stream sobre `runs`.
mux.HandleFunc("GET /api/datafactory/nodes", s.handleDataFactoryNodes)
mux.HandleFunc("GET /api/datafactory/runs", s.handleDataFactoryRuns)
mux.HandleFunc("GET /api/datafactory/databases", s.handleDataFactoryDatabases)
mux.HandleFunc("GET /api/ws/datafactory", s.handleDataFactoryEvents(s.dfHub))
}
func (s *Server) handleHealth(w http.ResponseWriter, r *http.Request) {
@@ -62,9 +106,14 @@ func (s *Server) handleDatabases(w http.ResponseWriter, r *http.Request) {
Alias string `json:"alias"`
Kind string `json:"kind"`
}
out := make([]dbInfo, len(entries))
for i, e := range entries {
out[i] = dbInfo{Alias: e.Alias, Kind: e.Kind}
out := make([]dbInfo, 0, len(entries)+1)
for _, e := range entries {
out = append(out, dbInfo{Alias: e.Alias, Kind: e.Kind})
}
// Surface data_factory.db too. It is opened RW outside the pool but
// belongs in the discovery list so dashboards can see it.
if s.dfPath != "" {
out = append(out, dbInfo{Alias: "data_factory", Kind: "data_factory"})
}
writeJSON(w, http.StatusOK, out)
}