Skip to content

Commit 62bcd12

Browse files
committed
fix: set network operations timeouts for miners discovery
1 parent a0f67db commit 62bcd12

4 files changed

Lines changed: 43 additions & 37 deletions

File tree

‎miners/avalon.go‎

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,7 @@ func getAddresses(ctx context.Context, network string) iter.Seq[netip.Addr] {
367367
return
368368
default:
369369
}
370-
370+
371371
if !yield(next) {
372372
return
373373
}
@@ -454,7 +454,9 @@ func version(ctx context.Context, address string, port int) (*AvalonQVersion, er
454454
}
455455

456456
func send[T any](ctx context.Context, address string, port int, sender Sender, receiver Receiver[T]) (T, error) {
457-
var d net.Dialer
457+
d := net.Dialer{
458+
Timeout: time.Second,
459+
}
458460
ctx, cancel := context.WithTimeout(ctx, time.Second)
459461
defer cancel()
460462

@@ -465,6 +467,12 @@ func send[T any](ctx context.Context, address string, port int, sender Sender, r
465467
}
466468
defer conn.Close()
467469

470+
// Set deadline for all operations on this connection
471+
if err := conn.SetDeadline(time.Now().Add(2 * time.Second)); err != nil {
472+
var zero T
473+
return zero, err
474+
}
475+
468476
if err := sender(conn); err != nil {
469477
var zero T
470478
return zero, err

‎scheduler/miners.go‎

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,21 +21,22 @@ func (s *MinerScheduler) discoverMiners(ctx context.Context) error {
2121
newlyDiscoveredMiners = miners.Discover(ctx, s.config.Network)
2222
}
2323

24-
s.mu.Lock()
25-
defer s.mu.Unlock()
26-
2724
// Add only new miners that don't already exist
2825
newMinersCount := 0
2926
for _, newMiner := range newlyDiscoveredMiners {
3027
key := fmt.Sprintf("%s:%d", newMiner.Address, newMiner.Port)
31-
if _, exists := s.discoveredMiners[key]; !exists {
32-
s.discoveredMiners[key] = newMiner
28+
if _, exists := s.discoveredMiners.LoadOrStore(key, newMiner); !exists {
3329
newMinersCount++
3430
s.logger.Printf(" New miner discovered: %s:%d", newMiner.Address, newMiner.Port)
3531
}
3632
}
3733

38-
totalMiners := len(s.discoveredMiners)
34+
// Count total miners
35+
totalMiners := 0
36+
s.discoveredMiners.Range(func(_, _ any) bool {
37+
totalMiners++
38+
return true
39+
})
3940
s.logger.Printf("Discovery complete: %d total miners (%d newly discovered)", totalMiners, newMinersCount)
4041

4142
return nil

‎scheduler/scheduler.go‎

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ type MinerScheduler struct {
8585
config *Config
8686

8787
// State
88-
discoveredMiners map[string]*miners.AvalonQHost
88+
discoveredMiners sync.Map // map[string]*miners.AvalonQHost
8989
pricesMarketData *entsoe.PublicationMarketData
9090
pricesMarketDataExpiry time.Time
9191
isRunning bool
@@ -119,10 +119,9 @@ func NewMinerScheduler(config *Config, logger *log.Logger) *MinerScheduler {
119119
}
120120

121121
scheduler := &MinerScheduler{
122-
config: config,
123-
discoveredMiners: make(map[string]*miners.AvalonQHost),
124-
stopChan: make(chan struct{}),
125-
logger: logger,
122+
config: config,
123+
stopChan: make(chan struct{}),
124+
logger: logger,
126125
weatherCache: WeatherForecastCache{
127126
cacheDuration: 2 * time.Hour,
128127
},
@@ -154,14 +153,14 @@ func (s *MinerScheduler) GetConfig() *Config {
154153

155154
// GetDiscoveredMiners returns a copy of the currently discovered miners
156155
func (s *MinerScheduler) GetDiscoveredMiners() []*miners.AvalonQHost {
157-
s.mu.RLock()
158-
defer s.mu.RUnlock()
159-
160-
// Convert map to slice and return a copy
161-
minersCopy := make([]*miners.AvalonQHost, 0, len(s.discoveredMiners))
162-
for _, miner := range s.discoveredMiners {
163-
minersCopy = append(minersCopy, miner)
164-
}
156+
// Convert sync.Map to slice
157+
minersCopy := make([]*miners.AvalonQHost, 0)
158+
s.discoveredMiners.Range(func(_, value any) bool {
159+
if miner, ok := value.(*miners.AvalonQHost); ok {
160+
minersCopy = append(minersCopy, miner)
161+
}
162+
return true
163+
})
165164
return minersCopy
166165
}
167166

@@ -366,9 +365,16 @@ func (s *MinerScheduler) GetStatus() Status {
366365
s.mu.RLock()
367366
defer s.mu.RUnlock()
368367

368+
// Count miners in sync.Map
369+
minersCount := 0
370+
s.discoveredMiners.Range(func(_, _ any) bool {
371+
minersCount++
372+
return true
373+
})
374+
369375
return Status{
370376
IsRunning: s.isRunning,
371-
MinersCount: len(s.discoveredMiners),
377+
MinersCount: minersCount,
372378
HasMarketData: s.pricesMarketData != nil,
373379
}
374380
}

‎scheduler/scheduler_test.go‎

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -315,13 +315,10 @@ func TestGetDiscoveredMiners(t *testing.T) {
315315
{Address: "192.168.1.101", Port: 4028},
316316
}
317317

318-
scheduler.mu.Lock()
319-
scheduler.discoveredMiners = make(map[string]*miners.AvalonQHost)
320318
for _, miner := range mockMiners {
321319
key := fmt.Sprintf("%s:%d", miner.Address, miner.Port)
322-
scheduler.discoveredMiners[key] = miner
320+
scheduler.discoveredMiners.Store(key, miner)
323321
}
324-
scheduler.mu.Unlock()
325322

326323
// Test getting miners
327324
retrievedMiners := scheduler.GetDiscoveredMiners()
@@ -352,13 +349,10 @@ func TestDiscoverMinersPreservesExisting(t *testing.T) {
352349
{Address: "192.168.1.101", Port: 4028},
353350
}
354351

355-
scheduler.mu.Lock()
356-
scheduler.discoveredMiners = make(map[string]*miners.AvalonQHost)
357352
for _, miner := range initialMiners {
358353
key := fmt.Sprintf("%s:%d", miner.Address, miner.Port)
359-
scheduler.discoveredMiners[key] = miner
354+
scheduler.discoveredMiners.Store(key, miner)
360355
}
361-
scheduler.mu.Unlock()
362356

363357
// Run discovery (should not find anything on 127.0.0.1/32, but existing miners should be preserved)
364358
err := scheduler.discoverMiners(context.Background())
@@ -422,12 +416,11 @@ func TestSchedulerStatus_WithData(t *testing.T) {
422416
CreatedDateTime: "2024-01-15T10:30:00Z",
423417
}
424418

425-
scheduler.mu.Lock()
426-
scheduler.discoveredMiners = make(map[string]*miners.AvalonQHost)
427419
for _, miner := range mockMiners {
428420
key := fmt.Sprintf("%s:%d", miner.Address, miner.Port)
429-
scheduler.discoveredMiners[key] = miner
421+
scheduler.discoveredMiners.Store(key, miner)
430422
}
423+
scheduler.mu.Lock()
431424
scheduler.pricesMarketData = mockDoc
432425
scheduler.mu.Unlock()
433426

@@ -495,10 +488,9 @@ func BenchmarkSchedulerGetStatus(b *testing.B) {
495488
Port: 4028,
496489
}
497490
}
498-
scheduler.discoveredMiners = make(map[string]*miners.AvalonQHost)
499491
for _, miner := range mockMiners {
500492
key := fmt.Sprintf("%s:%d", miner.Address, miner.Port)
501-
scheduler.discoveredMiners[key] = miner
493+
scheduler.discoveredMiners.Store(key, miner)
502494
}
503495

504496
for b.Loop() {
@@ -654,10 +646,9 @@ func BenchmarkSchedulerGetDiscoveredMiners(b *testing.B) {
654646
Port: 4028,
655647
}
656648
}
657-
scheduler.discoveredMiners = make(map[string]*miners.AvalonQHost)
658649
for _, miner := range mockMiners {
659650
key := fmt.Sprintf("%s:%d", miner.Address, miner.Port)
660-
scheduler.discoveredMiners[key] = miner
651+
scheduler.discoveredMiners.Store(key, miner)
661652
}
662653

663654
for b.Loop() {

0 commit comments

Comments
 (0)