-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.go
More file actions
118 lines (99 loc) · 3.04 KB
/
Copy pathmain.go
File metadata and controls
118 lines (99 loc) · 3.04 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
package main
import (
"log"
"net/http"
"os"
"strconv"
"strings"
"time"
"github.com/gorilla/mux"
)
var nodeID int
var httpPort string
var peerPorts []string
var peerHosts []string // optional container hostnames (PEER_HOSTS env)
func main() {
id, _ := strconv.Atoi(os.Getenv("NODE_ID"))
nodeID = id
httpPort = os.Getenv("HTTP_PORT")
if httpPort == "" {
httpPort = "8080"
}
peers := os.Getenv("PEER_PORTS")
if peers != "" {
for _, p := range strings.Split(peers, ",") {
p = strings.TrimSpace(p)
if p != "" {
peerPorts = append(peerPorts, p)
}
}
}
hosts := os.Getenv("PEER_HOSTS")
if hosts != "" {
for _, h := range strings.Split(hosts, ",") {
h = strings.TrimSpace(h)
if h != "" {
peerHosts = append(peerHosts, h)
}
}
}
initDB()
initMembership()
go startHub()
go runElection()
go runWatchdog()
go runTriageAgent()
r := mux.NewRouter()
// Health & cluster
r.HandleFunc("/health", handleHealth).Methods("GET")
r.HandleFunc("/current-leader", handleCurrentLeader).Methods("GET")
r.HandleFunc("/replication-summary", handleReplicationSummary).Methods("GET")
r.HandleFunc("/reset", handleReset).Methods("POST")
// Public API
r.HandleFunc("/api/network", handleNetwork).Methods("GET")
r.HandleFunc("/api/satellites", handleSatellites).Methods("GET")
r.HandleFunc("/api/conjunctions", handleConjunctions).Methods("GET")
r.HandleFunc("/api/maneuver/request", handleManeuverRequest).Methods("POST")
r.HandleFunc("/api/maneuver/emergency", handleEmergencyOverride).Methods("POST")
r.HandleFunc("/api/agent/toggle", handleAgentToggle).Methods("POST")
// Node chaos control
r.HandleFunc("/control/node/{id}/{action}", handleNodeControl).Methods("POST")
// Internal consensus messages
r.HandleFunc("/internal/prepare", handleInternalPrepare).Methods("POST")
r.HandleFunc("/internal/commit", handleInternalCommit).Methods("POST")
r.HandleFunc("/internal/abort", handleInternalAbort).Methods("POST")
// Internal election messages
r.HandleFunc("/internal/election", handleElectionMsg).Methods("POST")
r.HandleFunc("/internal/coordinator", handleCoordinatorMsg).Methods("POST")
// WebSocket
r.HandleFunc("/ws", handleWebSocket)
// CORS middleware
handler := corsMiddleware(r)
log.Printf("[AstroMesh] Node %d starting on :%s peers=%v", nodeID, httpPort, peerPorts)
srv := &http.Server{
Addr: ":" + httpPort,
Handler: handler,
ReadTimeout: 15 * time.Second,
WriteTimeout: 15 * time.Second,
}
log.Fatal(srv.ListenAndServe())
}
func corsMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Access-Control-Allow-Methods", "GET, POST, OPTIONS")
w.Header().Set("Access-Control-Allow-Headers", "Content-Type")
if r.Method == http.MethodOptions {
w.WriteHeader(http.StatusNoContent)
return
}
next.ServeHTTP(w, r)
})
}
func runWatchdog() {
ticker := time.NewTicker(10 * time.Second)
defer ticker.Stop()
for range ticker.C {
broadcastNetworkUpdate()
}
}