github.com/mysteriumnetwork/node@v0.0.0-20240516044423-365054f76801/core/connection/stats_publisher.go (about) 1 /* 2 * Copyright (C) 2020 The "MysteriumNetwork/node" Authors. 3 * 4 * This program is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation, either version 3 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18 package connection 19 20 import ( 21 "sync" 22 "time" 23 24 "github.com/rs/zerolog/log" 25 26 "github.com/mysteriumnetwork/node/core/connection/connectionstate" 27 "github.com/mysteriumnetwork/node/eventbus" 28 ) 29 30 type statsSupplier interface { 31 Statistics() (connectionstate.Statistics, error) 32 } 33 34 type statsTracker struct { 35 done chan struct{} 36 bus eventbus.Publisher 37 interval time.Duration 38 39 mu sync.RWMutex 40 lastStats connectionstate.Statistics 41 } 42 43 func newStatsTracker(bus eventbus.Publisher, interval time.Duration) statsTracker { 44 return statsTracker{ 45 done: make(chan struct{}), 46 bus: bus, 47 interval: interval, 48 } 49 } 50 51 func (s *statsTracker) start(sessionSupplier *connectionManager, statsSupplier statsSupplier) { 52 for { 53 select { 54 case <-time.After(s.interval): 55 stats, err := statsSupplier.Statistics() 56 if err != nil { 57 log.Warn().Err(err).Msg("Could not get connection statistics") 58 continue 59 } 60 61 s.bus.Publish(connectionstate.AppTopicConnectionStatistics, connectionstate.AppEventConnectionStatistics{ 62 Stats: stats, 63 UUID: sessionSupplier.UUID(), 64 SessionInfo: sessionSupplier.Status(), 65 }) 66 67 s.mu.Lock() 68 s.lastStats = stats 69 s.mu.Unlock() 70 71 case <-s.done: 72 log.Info().Msg("Stopped publishing connection statistics") 73 return 74 } 75 } 76 } 77 78 func (s *statsTracker) stats() connectionstate.Statistics { 79 s.mu.RLock() 80 defer s.mu.RUnlock() 81 82 return s.lastStats 83 } 84 85 func (s *statsTracker) stop() { 86 s.done <- struct{}{} 87 }