discovery: prevent double-close panic; fix IPv6 URLs & expiration guard
Signed-off-by: NotAShelf <raf@notashelf.dev> Change-Id: I9f7b1a34065de77f4a8982b0f5feebc86a6a6964
This commit is contained in:
parent
5fc3b2883b
commit
0f62641d23
1 changed files with 8 additions and 3 deletions
|
|
@ -4,6 +4,7 @@ import (
|
|||
"context"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"net"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
|
|
@ -20,6 +21,7 @@ type Discovery struct {
|
|||
discovered map[string]*discoveredPeer
|
||||
mu sync.RWMutex
|
||||
stopCh chan struct{}
|
||||
stopOnce sync.Once
|
||||
waitGroup sync.WaitGroup
|
||||
onAddUpstream func(url string, priority int)
|
||||
onRemoveUpstream func(url string)
|
||||
|
|
@ -71,6 +73,7 @@ func (d *Discovery) Start(ctx context.Context) error {
|
|||
|
||||
if err := d.resolver.Browse(ctx, d.cfg.ServiceName, d.cfg.Domain, entries); err != nil {
|
||||
close(entries)
|
||||
d.stopOnce.Do(func() { close(d.stopCh) })
|
||||
d.waitGroup.Wait()
|
||||
return fmt.Errorf("browse services: %w", err)
|
||||
}
|
||||
|
|
@ -85,7 +88,7 @@ func (d *Discovery) Start(ctx context.Context) error {
|
|||
|
||||
// Stops the discovery process.
|
||||
func (d *Discovery) Stop() {
|
||||
close(d.stopCh)
|
||||
d.stopOnce.Do(func() { close(d.stopCh) })
|
||||
d.waitGroup.Wait()
|
||||
}
|
||||
|
||||
|
|
@ -122,8 +125,7 @@ func (d *Discovery) handleEntry(_ context.Context, entry *zeroconf.ServiceEntry)
|
|||
addr = entry.AddrIPv6[0].String()
|
||||
}
|
||||
|
||||
port := entry.Port
|
||||
url := fmt.Sprintf("http://%s:%d", addr, port)
|
||||
url := "http://" + net.JoinHostPort(addr, fmt.Sprintf("%d", entry.Port))
|
||||
key := fmt.Sprintf("%s@%s", entry.Instance, entry.HostName)
|
||||
|
||||
d.mu.Lock()
|
||||
|
|
@ -184,6 +186,9 @@ func (d *Discovery) cleanupPeers() {
|
|||
// TTL is the discovery response time; peers should re-announce periodically.
|
||||
// Use 3x TTL as the expiration window.
|
||||
expiration := d.cfg.DiscoveryTime.Duration * 3
|
||||
if expiration == 0 {
|
||||
expiration = time.Second
|
||||
}
|
||||
|
||||
for key, peer := range d.discovered {
|
||||
if now.Sub(peer.lastSeen) > expiration {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue