@@ -322,33 +322,52 @@ func (s *StatsItem) UnmarshalJSON(data []byte) error {
322322
323323// Discover searches for Avalon miners on the specified network and returns a list of discovered hosts.
324324func Discover (ctx context.Context , network string ) []* AvalonQHost {
325- hosts := make ([] * AvalonQHost , 0 )
325+ results := make (chan * AvalonQHost )
326326 var wg sync.WaitGroup
327327 queue := make (chan string , 25 )
328- for a := range getAddresses (network ) {
328+
329+ // Collector goroutine - single writer to hosts slice
330+ hosts := make ([]* AvalonQHost , 0 )
331+ done := make (chan struct {})
332+ go func () {
333+ for host := range results {
334+ hosts = append (hosts , host )
335+ }
336+ close (done )
337+ }()
338+
339+ for a := range getAddresses (ctx , network ) {
329340 address := a .String ()
330341 queue <- address
331342 wg .Go (func () {
332343 if v , err := version (ctx , address , 4028 ); err == nil {
333- hosts = append ( hosts , & AvalonQHost {
344+ results <- & AvalonQHost {
334345 Address : address ,
335346 Port : 4028 ,
336347 Version : v ,
337- })
348+ }
338349 }
339350 <- queue
340351 })
341352 }
342353 wg .Wait ()
343- close (queue )
354+ close (results )
355+ <- done
344356 return hosts
345357}
346358
347- func getAddresses (network string ) iter.Seq [netip.Addr ] {
359+ func getAddresses (ctx context. Context , network string ) iter.Seq [netip.Addr ] {
348360 return func (yield func (netip.Addr ) bool ) {
349361 prefix , _ := netip .ParsePrefix (network )
350362 next := prefix .Addr ().Next ()
351363 for next .IsValid () && prefix .Contains (next .Next ()) {
364+ // Check if context is cancelled before yielding each address
365+ select {
366+ case <- ctx .Done ():
367+ return
368+ default :
369+ }
370+
352371 if ! yield (next ) {
353372 return
354373 }
0 commit comments