beacon v2 discovery: advertise metamesh.core + service resources on 239.255.99.1:9099, /api/neighbors ?cap= filter
Build and Push Docker Image / build (push) Failing after 14s

This commit is contained in:
Worph
2026-10-04 11:51:03 +00:00
parent 9254f043a4
commit 27ed45999b
10 changed files with 559 additions and 284 deletions
+14 -5
View File
@@ -550,11 +550,11 @@ func (s *Server) handleGetFileByCID(w http.ResponseWriter, r *http.Request) {
// handleListNeighbors handles GET /neighbors and GET /api/neighbors.
//
// meta-discovery v1. The list is built from UDP announces held in memory, not
// from files under /meta-core/services, so it works across stacks that share a
// network but no volume. Instances of the same service are collapsed to the
// most recent, which preserves the one-row-per-service shape the old
// /api/services had. `?all=1` returns every instance, for debugging.
// Beacon v2 (docs/project-architecture/beacon-v2.md). The list is this node's
// in-memory view of the UDP group, so it works across stacks that share a
// network but no volume. Instances of one name collapse to the most recent
// (one row per service, the nav menu's shape); `?all=1` returns every
// instance, `?cap=<pattern>` keeps only nodes with a matching capability.
func (s *Server) handleListNeighbors(w http.ResponseWriter, r *http.Request) {
response := map[string]interface{}{
"current": s.config.ServiceName,
@@ -576,6 +576,15 @@ func (s *Server) handleListNeighbors(w http.ResponseWriter, r *http.Request) {
} else {
list = s.mesh.NeighborsByName()
}
if pattern := r.URL.Query().Get("cap"); pattern != "" {
kept := list[:0]
for _, nb := range list {
if nb.Matches(pattern) {
kept = append(kept, nb)
}
}
list = kept
}
response["enabled"] = true
response["neighbors"] = list
+2 -2
View File
@@ -43,7 +43,7 @@ type Server struct {
// challenges backs proof-of-possession on reveal/delete. In-process, so a
// restart invalidates the ones in flight — see identity/challenge.go.
challenges *identity.ChallengeStore
// mesh is the UDP discovery node (meta-discovery v1). nil when discovery
// mesh is the UDP discovery node (beacon v2). nil when discovery
// is disabled or failed to bind, in which case /api/neighbors reports an
// empty list rather than erroring — a dashboard nav is decoration and
// must not take the API down with it.
@@ -291,7 +291,7 @@ func (s *Server) setupRoutes() {
s.router.HandleFunc("/api/events/files", s.handleEventsFiles).Methods("GET")
s.router.HandleFunc("/api/events/meta", s.handleEventsMeta).Methods("GET")
// meta-discovery v1: neighbours heard over UDP. Supersedes /api/services,
// beacon v2: neighbours heard over UDP. Supersedes /api/services,
// which is still served above while consumers migrate.
s.router.HandleFunc("/neighbors", s.handleListNeighbors).Methods("GET")
s.router.HandleFunc("/api/neighbors", s.handleListNeighbors).Methods("GET")