feat: integrate 8.2 X-Service dispatcher into main router
Build and push / Build and push image (push) Successful in 55s
Build / Build and push image (push) Successful in 41s
CI / Test, vet, build (push) Failing after 45s

This commit is contained in:
Admin Bot
2026-08-26 14:05:43 -07:00
parent 951a4399d6
commit 0cdfae2a93
2 changed files with 45 additions and 15 deletions
+8 -2
View File
@@ -12,6 +12,7 @@ import (
"forgejo.riotpiao.com/rock/homelab-frontend/internal/config" "forgejo.riotpiao.com/rock/homelab-frontend/internal/config"
"forgejo.riotpiao.com/rock/homelab-frontend/internal/proxy" "forgejo.riotpiao.com/rock/homelab-frontend/internal/proxy"
"forgejo.riotpiao.com/rock/homelab-frontend/internal/server" "forgejo.riotpiao.com/rock/homelab-frontend/internal/server"
"forgejo.riotpiao.com/rock/homelab-frontend/internal/serviceadapter"
"forgejo.riotpiao.com/rock/homelab-frontend/internal/temporal" "forgejo.riotpiao.com/rock/homelab-frontend/internal/temporal"
) )
@@ -51,8 +52,13 @@ func main() {
healthChecker := server.NewHealthChecker(true, authEnabled) healthChecker := server.NewHealthChecker(true, authEnabled)
srv.SetHealthChecker(healthChecker) srv.SetHealthChecker(healthChecker)
// Create router that handles health endpoints, temporal endpoints, and passes others to upstream // Create ServiceAdapter registry and dispatcher (phase 8)
router := server.NewRouter(healthChecker, temporalHandler, upstreamHandler) registry := serviceadapter.NewRegistry(nil) // nil uses default logger
dispatcher := serviceadapter.NewDispatcher(registry)
// Create router that handles health endpoints, X-Service (ServiceAdapter) routing,
// temporal endpoints, and passes others to upstream handler
router := server.NewRouter(healthChecker, dispatcher, temporalHandler, upstreamHandler)
srv.SetHandler(router) srv.SetHandler(router)
// Set up signal handling // Set up signal handling
+37 -13
View File
@@ -2,42 +2,66 @@ package server
import ( import (
"net/http" "net/http"
"forgejo.riotpiao.com/rock/homelab-frontend/internal/serviceadapter"
) )
// Router implements an HTTP handler that routes health endpoints, // Router implements an HTTP handler that routes health endpoints,
// Temporal workflow endpoints, and other requests to upstream handlers. // ServiceAdapter X-Service requests, Temporal workflow endpoints,
// and other requests to upstream handlers.
type Router struct { type Router struct {
healthChecker *HealthChecker healthChecker *HealthChecker
dispatcher *serviceadapter.Dispatcher
temporalHandler http.Handler temporalHandler http.Handler
upstreamHandler http.Handler upstreamHandler http.Handler
} }
// NewRouter creates a new router with health endpoints. // NewRouter creates a new router with health endpoints.
// Health endpoints (/healthz and /readyz) are handled locally. // Health endpoints (/healthz and /readyz) are handled locally.
// X-Service requests are dispatched via ServiceAdapter CRD.
// Temporal endpoints (/workflow*) are routed to temporalHandler. // Temporal endpoints (/workflow*) are routed to temporalHandler.
// All other paths are passed to the upstream handler. // All other paths are passed to the upstream handler.
func NewRouter(healthChecker *HealthChecker, temporalHandler http.Handler, upstreamHandler http.Handler) *Router { func NewRouter(healthChecker *HealthChecker, dispatcher *serviceadapter.Dispatcher, temporalHandler http.Handler, upstreamHandler http.Handler) *Router {
return &Router{ return &Router{
healthChecker: healthChecker, healthChecker: healthChecker,
dispatcher: dispatcher,
temporalHandler: temporalHandler, temporalHandler: temporalHandler,
upstreamHandler: upstreamHandler, upstreamHandler: upstreamHandler,
} }
} }
// ServeHTTP implements http.Handler. // ServeHTTP implements http.Handler.
// It routes /healthz and /readyz to health handlers, // Priority order:
// /workflow* to the temporal handler, // 1. /healthz and /readyz to health handlers
// and passes all other paths to the upstream handler. // 2. X-Service header to ServiceAdapter dispatcher (phase 8)
// 3. /workflow* to temporal handler
// 4. All other paths to upstream handler (phase 0-7)
func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request) { func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request) {
switch { // Health endpoints first
case req.URL.Path == "/healthz": switch req.URL.Path {
case "/healthz":
LivenessHandler(r.healthChecker)(w, req) LivenessHandler(r.healthChecker)(w, req)
case req.URL.Path == "/readyz": return
case "/readyz":
ReadinessHandler(r.healthChecker)(w, req) ReadinessHandler(r.healthChecker)(w, req)
case req.URL.Path == "/workflow" || req.URL.Path == "/workflow/health" || req.URL.Path == "/workflow/metrics": return
// Route all /workflow endpoints to temporal handler
r.temporalHandler.ServeHTTP(w, req)
default:
r.upstreamHandler.ServeHTTP(w, req)
} }
// X-Service (ServiceAdapter) routing - checked before path-based routing
if req.Header.Get("X-Service") != "" {
if r.dispatcher != nil {
r.dispatcher.Dispatch(w, req)
return
}
}
// Workflow endpoints
switch req.URL.Path {
case "/workflow", "/workflow/health", "/workflow/metrics":
r.temporalHandler.ServeHTTP(w, req)
return
}
// Default: upstream handler (all other paths)
r.upstreamHandler.ServeHTTP(w, req)
} }