Files
pangolin/server/internal/nodes/service.go
T
wangjia 8ed1cfcc75 merge: gRPC server + hub + 跨实例 pub/sub [tsk_mF5RWPEwngai]
Resolve merge conflict between maestro/tsk__58l3wTLvaSn (gRPC nodes feature)
and main (admin backend + JWT config + OpenAPI routes):

- server/cmd/server/main.go: keep admin backend (startAdminIfConfigured) AND
  add gRPC agent server (startGRPC) — both coexist as independent optional
  listeners governed by their respective env vars
- server/internal/config/config.go: keep JWT fields (JWTPrivateKeyPath /
  JWTKeyID / JWTPublicKeys) AND add gRPC fields (GRPCAddr / CAKeyPath /
  CACertPath / GRPCCertPath / GRPCKeyPath)
- server/internal/nodes/: add all new files from tsk__58l3wTLvaSn
  (hub.go, hub_test.go, load.go, handler_grpc.go, grpc_test.go,
   service.go, store.go) — 18 tests, all passing

Test: go test ./internal/nodes/... → PASS (18/18)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-13 20:10:01 +08:00

61 lines
1.5 KiB
Go

package nodes
import (
"github.com/redis/go-redis/v9"
"github.com/wangjia/pangolin/server/internal/mtls"
agentv1 "github.com/wangjia/pangolin/server/internal/pb/agentv1"
)
// Service bundles all nodes-domain components and exposes assembly helpers.
// Construct via NewService after initialising each dependency independently.
type Service struct {
handler *Handler
hub *Hub
store NodeStore
load *LoadCache
}
// NewService wires up the full nodes service from its dependencies.
//
// - ca / tokens / crl: from the mtls package (task 5b)
// - rdb: Redis client (for hub + load cache)
// - store: NodeStore implementation (SQLNodeStore in production; mock in tests)
func NewService(
ca *mtls.CA,
tokens *mtls.BootstrapTokenManager,
rdb *redis.Client,
store NodeStore,
) *Service {
hub := NewHub(rdb)
load := NewLoadCache(rdb)
handler := NewHandler(ca, tokens, hub, store, load)
return &Service{
handler: handler,
hub: hub,
store: store,
load: load,
}
}
// Handler returns the AgentServiceServer implementation for gRPC registration.
func (s *Service) Handler() agentv1.AgentServiceServer {
return s.handler
}
// Hub exposes the command routing hub for callers (e.g. task 5d/5e) that need to
// Push or Broadcast commands.
func (s *Service) Hub() *Hub {
return s.hub
}
// Store exposes the NodeStore for callers that need direct DB access.
func (s *Service) Store() NodeStore {
return s.store
}
// Load exposes the LoadCache for callers that display per-node load metrics.
func (s *Service) Load() *LoadCache {
return s.load
}