@@ -18,14 +18,18 @@ type DiscoveryClient struct {
1818 tailscale * Tailscale
1919 cfg BlobCacheConfig
2020 hostMap * HostMap
21+ metadata * BlobCacheMetadata
2122 mu sync.Mutex
23+ tsClient * tailscale.LocalClient
2224}
2325
24- func NewDiscoveryClient (cfg BlobCacheConfig , tailscale * Tailscale , hostMap * HostMap ) * DiscoveryClient {
26+ func NewDiscoveryClient (cfg BlobCacheConfig , tailscale * Tailscale , hostMap * HostMap , metadata * BlobCacheMetadata ) * DiscoveryClient {
2527 return & DiscoveryClient {
2628 cfg : cfg ,
2729 tailscale : tailscale ,
2830 hostMap : hostMap ,
31+ metadata : metadata ,
32+ tsClient : nil ,
2933 }
3034}
3135
@@ -37,17 +41,26 @@ func (d *DiscoveryClient) updateHostMap(newHosts []*BlobCacheHost) {
3741
3842// Used by blobcache servers to discover their closest peers
3943func (d * DiscoveryClient ) StartInBackground (ctx context.Context ) error {
40- server , err := d . tailscale . GetOrCreateServer ()
41- if err != nil {
42- return err
44+ // Default to metadata discovery if no mode is specified
45+ if d . cfg . DiscoveryMode == "" {
46+ d . cfg . DiscoveryMode = string ( DiscoveryModeMetadata )
4347 }
4448
45- client , err := server .LocalClient ()
46- if err != nil {
47- return err
49+ if d .cfg .DiscoveryMode == string (DiscoveryModeTailscale ) {
50+ server , err := d .tailscale .GetOrCreateServer ()
51+ if err != nil {
52+ return err
53+ }
54+
55+ client , err := server .LocalClient ()
56+ if err != nil {
57+ return err
58+ }
59+
60+ d .tsClient = client
4861 }
4962
50- hosts , err := d .FindNearbyHosts (ctx , client )
63+ hosts , err := d .FindNearbyHosts (ctx )
5164 if err == nil {
5265 d .updateHostMap (hosts )
5366 }
@@ -56,7 +69,7 @@ func (d *DiscoveryClient) StartInBackground(ctx context.Context) error {
5669 for {
5770 select {
5871 case <- ticker .C :
59- hosts , err := d .FindNearbyHosts (ctx , client )
72+ hosts , err := d .FindNearbyHosts (ctx )
6073 if err != nil {
6174 continue
6275 }
@@ -68,8 +81,8 @@ func (d *DiscoveryClient) StartInBackground(ctx context.Context) error {
6881 }
6982}
7083
71- func (d * DiscoveryClient ) FindNearbyHosts (ctx context.Context , client * tailscale. LocalClient ) ([]* BlobCacheHost , error ) {
72- status , err := client .Status (ctx )
84+ func (d * DiscoveryClient ) discoverHostsViaTailscale (ctx context.Context ) ([]* BlobCacheHost , error ) {
85+ status , err := d . tsClient .Status (ctx )
7386 if err != nil {
7487 return nil , err
7588 }
@@ -87,6 +100,8 @@ func (d *DiscoveryClient) FindNearbyHosts(ctx context.Context, client *tailscale
87100 wg .Add (1 )
88101
89102 go func (hostname string ) {
103+ Logger .Debugf ("Discovered host: %s" , hostname )
104+
90105 defer wg .Done ()
91106
92107 hostname = hostname [:len (hostname )- 1 ] // Strip the last period
@@ -105,7 +120,6 @@ func (d *DiscoveryClient) FindNearbyHosts(ctx context.Context, client *tailscale
105120 d .mu .Lock ()
106121 defer d .mu .Unlock ()
107122 hosts = append (hosts , host )
108-
109123 }(peer .DNSName )
110124 }
111125 }
@@ -114,6 +128,69 @@ func (d *DiscoveryClient) FindNearbyHosts(ctx context.Context, client *tailscale
114128 return hosts , nil
115129}
116130
131+ func (d * DiscoveryClient ) discoverHostsViaMetadata (ctx context.Context ) ([]* BlobCacheHost , error ) {
132+ hosts , err := d .metadata .GetAvailableHosts (ctx )
133+ if err != nil {
134+ return nil , err
135+ }
136+
137+ var wg sync.WaitGroup
138+ filteredHosts := []* BlobCacheHost {}
139+ mu := sync.Mutex {}
140+
141+ for _ , host := range hosts {
142+ if host .PrivateAddr != "" {
143+ addr := fmt .Sprintf ("%s:%d" , host .PrivateAddr , d .cfg .Port )
144+
145+ // Don't try to get the state on peers we're already aware of
146+ if d .hostMap .Get (addr ) != nil {
147+ continue
148+ }
149+
150+ wg .Add (1 )
151+ go func (addr string ) {
152+ defer wg .Done ()
153+
154+ hostState , err := d .GetHostState (ctx , addr )
155+ if err != nil {
156+ return
157+ }
158+
159+ mu .Lock ()
160+ filteredHosts = append (filteredHosts , hostState )
161+ mu .Unlock ()
162+
163+ Logger .Debugf ("Added host with private address to map: %s" , hostState .PrivateAddr )
164+ }(addr )
165+ }
166+ }
167+
168+ wg .Wait ()
169+ return filteredHosts , nil
170+ }
171+
172+ func (d * DiscoveryClient ) FindNearbyHosts (ctx context.Context ) ([]* BlobCacheHost , error ) {
173+ var hosts []* BlobCacheHost
174+ var err error
175+
176+ switch d .cfg .DiscoveryMode {
177+ case string (DiscoveryModeTailscale ):
178+ hosts , err = d .discoverHostsViaTailscale (ctx )
179+ if err != nil {
180+ return nil , err
181+ }
182+ case string (DiscoveryModeMetadata ):
183+ hosts , err = d .discoverHostsViaMetadata (ctx )
184+ if err != nil {
185+ return nil , err
186+ }
187+ default :
188+ return nil , fmt .Errorf ("invalid discovery mode: %s" , d .cfg .DiscoveryMode )
189+ }
190+
191+ return hosts , nil
192+ }
193+
117194// checkService attempts to connect to the gRPC service and verifies its availability
118195func (d * DiscoveryClient ) GetHostState (ctx context.Context , addr string ) (* BlobCacheHost , error ) {
119196 host := BlobCacheHost {
0 commit comments