client: improve healthcheck
Kim committed
Oct 22, 2025 at 10:06 UTC
d353f66c6320787ae57563ef82a3bdbaff050f23
3 files changed
+41
-4
cmd/example_chat/main.go
+1
-1
@@ -30,7 +30,7 @@ func init() {
30
flags := rootCmd.PersistentFlags()
31
flags.StringVar(&flagServerURL, "server-url", "http://relaydns.gosuda.org", "relayserver base URL to auto-fetch multiaddrs from /health")
32
flags.IntVar(&flagPort, "port", 8091, "local chat HTTP port")
33
- flags.StringVar(&flagName, "name", "bangjang-chat", "backend display name")
33
+ flags.StringVar(&flagName, "name", "example-chat", "backend display name")
34
}
35
36
func main() {
cmd/example_http_client/main.go
+1
-1
@@ -31,7 +31,7 @@ func init() {
31
flags := rootCmd.PersistentFlags()
32
flags.StringVar(&flagServerURL, "server-url", "http://relaydns.gosuda.org", "relayserver admin base URL to auto-fetch multiaddrs from /health")
33
flags.IntVar(&flagPort, "port", 8081, "local backend HTTP port")
34
- flags.StringVar(&flagName, "name", "bangjang-backend", "backend display name shown on server UI")
34
+ flags.StringVar(&flagName, "name", "example-backend", "backend display name shown on server UI")
35
}
36
37
func main() {
relaydns/client.go
+39
-2
@@ -12,7 +12,9 @@ import (
12
pubsub "github.com/libp2p/go-libp2p-pubsub"
13
"github.com/libp2p/go-libp2p/core/host"
14
"github.com/libp2p/go-libp2p/core/network"
15
+ "github.com/libp2p/go-libp2p/core/peer"
16
"github.com/libp2p/go-libp2p/core/protocol"
17
+ ma "github.com/multiformats/go-multiaddr"
18
"github.com/rs/zerolog/log"
19
)
20
@@ -117,6 +119,19 @@ func (b *RelayClient) Start(ctx context.Context) error {
119
boot := b.resolveBootstraps()
120
if len(boot) > 0 {
121
ConnectBootstraps(ctx, b.h, boot)
122
+ // If a server URL is configured, only mark healthy if actually
123
+ // connected to the server peer (not just able to fetch /hosts).
124
+ if b.cfg.ServerURL != "" {
125
+ if addrs, err := fetchMultiaddrsFromHosts(b.cfg.ServerURL, b.cfg.HTTPTimeout); err == nil {
126
+ if pid, ok := serverPeerFromAddrs(addrs); ok {
127
+ if b.h.Network().Connectedness(pid) == network.Connected {
128
+ b.setServerHealthy(true)
129
+ } else {
130
+ b.setServerHealthy(false)
131
+ }
132
+ }
133
+ }
134
+ }
135
} else {
136
log.Warn().Msg("relaydns: no bootstrap sources provided (Bootstraps/ServerURL); discovery may fail")
137
}
@@ -191,7 +206,7 @@ func (b *RelayClient) resolveBootstraps() []string {
206
b.setServerHealthy(false)
207
log.Warn().Err(err).Msgf("relaydns: fetch /hosts from %s failed", b.cfg.ServerURL)
208
} else {
194
- b.setServerHealthy(true)
209
+ // Do not mark healthy yet; only after verifying libp2p connectivity
210
sortMultiaddrs(addrs, b.cfg.PreferQUIC, b.cfg.PreferLocal)
211
boot = append(boot, addrs...)
212
}
@@ -296,18 +311,40 @@ func (b *RelayClient) startRefreshLoop(ctx context.Context) {
311
log.Warn().Err(err).Msgf("refresh /hosts from %s failed", b.cfg.ServerURL)
312
continue
313
}
299
- b.setServerHealthy(true)
314
sortMultiaddrs(addrs, b.cfg.PreferQUIC, b.cfg.PreferLocal)
315
addrs = RemoveDuplicate(addrs)
316
if len(addrs) > 0 {
317
// Always attempt (re)connect; ConnectBootstraps handles dedupe and quiet logging
318
ConnectBootstraps(ctx, b.h, addrs)
319
+ // Only mark healthy if actually connected to server peer
320
+ if pid, ok := serverPeerFromAddrs(addrs); ok {
321
+ if b.h.Network().Connectedness(pid) == network.Connected {
322
+ b.setServerHealthy(true)
323
+ } else {
324
+ b.setServerHealthy(false)
325
+ }
326
+ }
327
}
328
}
329
}
330
}()
331
}
332
333
+// serverPeerFromAddrs extracts the first peer.ID found in the provided
334
+// multiaddrs. The server advertises its own addrs including /p2p/<peer>.
335
+func serverPeerFromAddrs(addrs []string) (peer.ID, bool) {
336
+ for _, s := range addrs {
337
+ m, err := ma.NewMultiaddr(s)
338
+ if err != nil {
339
+ continue
340
+ }
341
+ if ai, err := peer.AddrInfoFromP2pAddr(m); err == nil {
342
+ return ai.ID, true
343
+ }
344
+ }
345
+ return "", false
346
+}
347
+
348
// ServerStatus returns a human-friendly status regarding connection to ServerURL.
349
// If no ServerURL is configured, returns "N/A".
350
func (b *RelayClient) ServerStatus() string {