github.com/status-im/status-go@v1.1.0/services/ext/mailservers/connmonitor.go (about) 1 package mailservers 2 3 import ( 4 "sync" 5 "time" 6 7 "github.com/ethereum/go-ethereum/log" 8 9 "github.com/status-im/status-go/eth-node/types" 10 ) 11 12 // NewLastUsedConnectionMonitor returns pointer to the instance of LastUsedConnectionMonitor. 13 func NewLastUsedConnectionMonitor(ps *PeerStore, cache *Cache, eventSub EnvelopeEventSubscriber) *LastUsedConnectionMonitor { 14 return &LastUsedConnectionMonitor{ 15 ps: ps, 16 cache: cache, 17 eventSub: eventSub, 18 } 19 } 20 21 // LastUsedConnectionMonitor watches relevant events and reflects it in cache. 22 type LastUsedConnectionMonitor struct { 23 ps *PeerStore 24 cache *Cache 25 26 eventSub EnvelopeEventSubscriber 27 28 quit chan struct{} 29 wg sync.WaitGroup 30 } 31 32 // Start spins a separate goroutine to watch connections. 33 func (mon *LastUsedConnectionMonitor) Start() { 34 mon.quit = make(chan struct{}) 35 mon.wg.Add(1) 36 go func() { 37 events := make(chan types.EnvelopeEvent, whisperEventsBuffer) 38 sub := mon.eventSub.SubscribeEnvelopeEvents(events) 39 defer sub.Unsubscribe() 40 defer mon.wg.Done() 41 for { 42 select { 43 case <-mon.quit: 44 return 45 case err := <-sub.Err(): 46 log.Error("retry after error suscribing to eventSub events", "error", err) 47 return 48 case ev := <-events: 49 node := mon.ps.Get(ev.Peer) 50 if node == nil { 51 continue 52 } 53 if ev.Event == types.EventMailServerRequestCompleted { 54 err := mon.updateRecord(ev.Peer) 55 if err != nil { 56 log.Error("unable to update storage", "peer", ev.Peer, "error", err) 57 } 58 } 59 } 60 } 61 }() 62 } 63 64 func (mon *LastUsedConnectionMonitor) updateRecord(nodeID types.EnodeID) error { 65 node := mon.ps.Get(nodeID) 66 if node == nil { 67 return nil 68 } 69 return mon.cache.UpdateRecord(PeerRecord{node: node, LastUsed: time.Now()}) 70 } 71 72 // Stop closes channel to signal a quit and waits until all goroutines are stoppped. 73 func (mon *LastUsedConnectionMonitor) Stop() { 74 if mon.quit == nil { 75 return 76 } 77 select { 78 case <-mon.quit: 79 return 80 default: 81 } 82 close(mon.quit) 83 mon.wg.Wait() 84 mon.quit = nil 85 }