chore: refactor codes
Kim committed
Oct 21, 2025 at 20:16 UTC
a2bc749eeeb75c89537194414dfa48ff22e609ba
5 files changed
+62
-52
cmd/server/view.go
+18
-24
@@ -27,7 +27,7 @@ func serveHTTP(ctx context.Context, addr string, d *relaydns.RelayServer, h host
27
http.NotFound(w, r)
28
return
29
}
30
- rows := make([]row, 0)
30
+ rows := make([]relaydns.AdminRow, 0)
31
for _, v := range d.Hosts() {
32
ttl := ""
33
if v.Info.TTL > 0 {
@@ -41,7 +41,7 @@ func serveHTTP(ctx context.Context, addr string, d *relaydns.RelayServer, h host
41
} else if strings.Contains(p, "http") {
42
kind = "HTTP"
43
}
44
- rows = append(rows, row{
44
+ rows = append(rows, relaydns.AdminRow{
45
Peer: v.Info.Peer,
46
Name: v.Info.Name,
47
DNS: v.Info.DNS,
@@ -54,7 +54,7 @@ func serveHTTP(ctx context.Context, addr string, d *relaydns.RelayServer, h host
54
}
55
w.Header().Set("Content-Type", "text/html; charset=utf-8")
56
log.Debug().Int("clients", len(rows)).Msg("render admin index")
57
- _ = adminIndexTmpl.Execute(w, page{
57
+ _ = adminIndexTmpl.Execute(w, relaydns.AdminPage{
58
NodeID: h.ID().String(),
59
Addrs: relaydns.BuildAddrs(h),
60
Rows: rows,
@@ -77,12 +77,24 @@ func serveHTTP(ctx context.Context, addr string, d *relaydns.RelayServer, h host
77
d.ProxyHTTP(w, r, peerID, pathSuffix)
78
})
79
80
- // JSON hosts
80
+ // JSON hosts (namespaced snapshot with server peer and connected peers only)
81
mux.HandleFunc("/hosts", func(w http.ResponseWriter, r *http.Request) {
82
- _ = json.NewEncoder(w).Encode(d.Hosts())
82
+ list := d.Hosts()
83
+ peers := make([]string, 0, len(list))
84
+ for _, v := range list {
85
+ if v.Connected {
86
+ peers = append(peers, v.Info.Peer)
87
+ }
88
+ }
89
+ snap := relaydns.Hosts{
90
+ ServerPeer: h.ID().String(),
91
+ ServerAddrs: relaydns.BuildAddrs(h),
92
+ Peers: peers,
93
+ }
94
+ w.Header().Set("Content-Type", "application/json")
95
+ _ = json.NewEncoder(w).Encode(snap)
96
})
97
85
- // Health
98
mux.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) {
99
type info struct {
100
Status string `json:"status"`
@@ -100,24 +112,6 @@ func serveHTTP(ctx context.Context, addr string, d *relaydns.RelayServer, h host
112
}
113
}
114
103
-// view model types used by template rendering
104
-type row struct {
105
- Peer string
106
- Name string
107
- DNS string
108
- LastSeen string
109
- Link string
110
- TTL string
111
- Connected bool
112
- Kind string
113
-}
114
-
115
-type page struct {
116
- NodeID string
117
- Addrs []string
118
- Rows []row
119
-}
120
-
115
var adminIndexTmpl = template.Must(template.New("admin-index").Parse(`<!doctype html>
116
<html lang="ko">
117
<head>
relaydns/client.go
+6
-6
@@ -180,16 +180,16 @@ func (b *RelayClient) resolveBootstraps() []string {
180
boot = append(boot, b.cfg.Bootstraps...)
181
}
182
if b.cfg.ServerURL != "" {
183
- if addrs, err := fetchMultiaddrsFromHealth(b.cfg.ServerURL, b.cfg.HTTPTimeout); err != nil {
183
+ if addrs, err := fetchMultiaddrsFromHosts(b.cfg.ServerURL, b.cfg.HTTPTimeout); err != nil {
184
b.setServerHealthy(false)
185
- log.Warn().Err(err).Msgf("relaydns: fetch /health from %s failed", b.cfg.ServerURL)
185
+ log.Warn().Err(err).Msgf("relaydns: fetch /hosts from %s failed", b.cfg.ServerURL)
186
} else {
187
b.setServerHealthy(true)
188
sortMultiaddrs(addrs, b.cfg.PreferQUIC, b.cfg.PreferLocal)
189
boot = append(boot, addrs...)
190
}
191
}
192
- return uniq(boot)
192
+ return RemoveDuplicate(boot)
193
}
194
195
// setupStreamHandler installs the appropriate libp2p stream handler.
@@ -273,15 +273,15 @@ func (b *RelayClient) startRefreshLoop(ctx context.Context) {
273
case <-ctx.Done():
274
return
275
case <-t.C:
276
- addrs, err := fetchMultiaddrsFromHealth(b.cfg.ServerURL, b.cfg.HTTPTimeout)
276
+ addrs, err := fetchMultiaddrsFromHosts(b.cfg.ServerURL, b.cfg.HTTPTimeout)
277
if err != nil {
278
b.setServerHealthy(false)
279
- log.Warn().Err(err).Msgf("refresh /health from %s failed", b.cfg.ServerURL)
279
+ log.Warn().Err(err).Msgf("refresh /hosts from %s failed", b.cfg.ServerURL)
280
continue
281
}
282
b.setServerHealthy(true)
283
sortMultiaddrs(addrs, b.cfg.PreferQUIC, b.cfg.PreferLocal)
284
- addrs = uniq(addrs)
284
+ addrs = RemoveDuplicate(addrs)
285
if len(addrs) > 0 {
286
// Always attempt (re)connect; ConnectBootstraps handles dedupe and quiet logging
287
ConnectBootstraps(ctx, b.h, addrs)
relaydns/server.go
+3
-5
@@ -103,10 +103,8 @@ func (s *RelayServer) collect() {
103
snap = append(snap, v)
104
}
105
s.storeMu.Unlock()
106
- if existed {
107
- log.Debug().Str("peer", ad.Peer).Str("name", ad.Name).Msg("server: updated client advert")
108
- } else {
109
- log.Info().Str("peer", ad.Peer).Str("name", ad.Name).Msg("server: added client")
106
+ if !existed {
107
+ log.Info().Str("peer", ad.Peer).Str("name", ad.Name).Msg("server: add new client")
108
}
109
_ = snap // snapshot kept local; selection handled explicitly via /peer
110
}
@@ -153,7 +151,7 @@ func (s *RelayServer) gc() {
151
}
152
s.storeMu.Unlock()
153
for _, r := range removed {
156
- log.Info().Str("peer", r.Info.Peer).Str("name", r.Info.Name).Dur("idle", now.Sub(r.LastSeen)).Msg("director: removed stale client")
154
+ log.Info().Str("peer", r.Info.Peer).Str("name", r.Info.Name).Dur("idle", now.Sub(r.LastSeen)).Msg("server: removed stale client")
155
}
156
_ = snap
157
}
relaydns/types.go
+26
@@ -12,6 +12,12 @@ const (
12
DefaultTopic = "relaydns.backends"
13
)
14
15
+type Hosts struct {
16
+ ServerPeer string `json:"serverPeer"`
17
+ ServerAddrs []string `json:"serverAddrs"`
18
+ Peers []string `json:"peers"` // connected peer IDs
19
+}
20
+
21
type Advertise struct {
22
Peer string `json:"peer"`
23
Name string `json:"name,omitempty"`
@@ -30,3 +36,23 @@ type HostEntry struct {
36
LastSeen time.Time
37
Connected bool
38
}
39
+
40
+// AdminPage is a simple view model used by the server admin UI template.
41
+// It intentionally lives here so other binaries can share the same model if needed.
42
+type AdminPage struct {
43
+ NodeID string
44
+ Addrs []string
45
+ Rows []AdminRow
46
+}
47
+
48
+// AdminRow represents a single backend entry as shown on the admin index.
49
+type AdminRow struct {
50
+ Peer string
51
+ Name string
52
+ DNS string
53
+ LastSeen string
54
+ Link string
55
+ TTL string
56
+ Connected bool
57
+ Kind string
58
+}
relaydns/utils.go
+9
-17
@@ -2,7 +2,6 @@ package relaydns
2
3
import (
4
"encoding/json"
5
- "errors"
5
"fmt"
6
"net/http"
7
"net/url"
@@ -42,7 +41,7 @@ func sortMultiaddrs(addrs []string, preferQUIC, preferLocal bool) {
41
sort.SliceStable(addrs, func(i, j int) bool { return score(addrs[i]) > score(addrs[j]) })
42
}
43
45
-func uniq(ss []string) []string {
44
+func RemoveDuplicate(ss []string) []string {
45
seen := map[string]struct{}{}
46
out := make([]string, 0, len(ss))
47
for _, s := range ss {
@@ -55,17 +54,17 @@ func uniq(ss []string) []string {
54
return out
55
}
56
58
-func fetchMultiaddrsFromHealth(base string, timeout time.Duration) ([]string, error) {
57
+func fetchMultiaddrsFromHosts(base string, timeout time.Duration) ([]string, error) {
58
u, err := url.Parse(base)
59
if err != nil {
60
return nil, fmt.Errorf("parse server-url: %w", err)
61
}
63
- // ensure path ends with /health
64
- if !strings.HasSuffix(u.Path, "/health") {
62
+ // ensure path ends with /hosts
63
+ if !strings.HasSuffix(u.Path, "/hosts") {
64
if u.Path == "" || u.Path == "/" {
66
- u.Path = "/health"
65
+ u.Path = "/hosts"
66
} else {
68
- u.Path = strings.TrimSuffix(u.Path, "/") + "/health"
67
+ u.Path = strings.TrimSuffix(u.Path, "/") + "/hosts"
68
}
69
}
70
client := &http.Client{Timeout: timeout}
@@ -76,19 +75,12 @@ func fetchMultiaddrsFromHealth(base string, timeout time.Duration) ([]string, er
75
}
76
defer resp.Body.Close()
77
79
- var payload struct {
80
- Status string `json:"status"`
81
- PeerID string `json:"peerId"`
82
- Multiaddrs []string `json:"multiaddrs"`
83
- }
78
+ var payload Hosts
79
if err := json.NewDecoder(resp.Body).Decode(&payload); err != nil {
80
return nil, err
81
}
87
- if payload.Status != "ok" {
88
- return nil, errors.New("health not ok")
89
- }
90
- addrs := make([]string, 0, len(payload.Multiaddrs))
91
- for _, s := range payload.Multiaddrs {
82
+ addrs := make([]string, 0, len(payload.ServerAddrs))
83
+ for _, s := range payload.ServerAddrs {
84
// sanity check
85
if strings.Contains(s, "/p2p/") && (strings.Contains(s, "/ip4/") || strings.Contains(s, "/ip6/")) {
86
addrs = append(addrs, s)