github.com/chwjbn/xclash@v0.2.0/tunnel/statistic/manager.go (about)

     1  package statistic
     2  
     3  import (
     4  	"sync"
     5  	"time"
     6  
     7  	"go.uber.org/atomic"
     8  )
     9  
    10  var DefaultManager *Manager
    11  
    12  func init() {
    13  	DefaultManager = &Manager{
    14  		uploadTemp:    atomic.NewInt64(0),
    15  		downloadTemp:  atomic.NewInt64(0),
    16  		uploadBlip:    atomic.NewInt64(0),
    17  		downloadBlip:  atomic.NewInt64(0),
    18  		uploadTotal:   atomic.NewInt64(0),
    19  		downloadTotal: atomic.NewInt64(0),
    20  	}
    21  
    22  	go DefaultManager.handle()
    23  }
    24  
    25  type Manager struct {
    26  	connections   sync.Map
    27  	uploadTemp    *atomic.Int64
    28  	downloadTemp  *atomic.Int64
    29  	uploadBlip    *atomic.Int64
    30  	downloadBlip  *atomic.Int64
    31  	uploadTotal   *atomic.Int64
    32  	downloadTotal *atomic.Int64
    33  }
    34  
    35  func (m *Manager) Join(c tracker) {
    36  	m.connections.Store(c.ID(), c)
    37  }
    38  
    39  func (m *Manager) Leave(c tracker) {
    40  	m.connections.Delete(c.ID())
    41  }
    42  
    43  func (m *Manager) PushUploaded(size int64) {
    44  	m.uploadTemp.Add(size)
    45  	m.uploadTotal.Add(size)
    46  }
    47  
    48  func (m *Manager) PushDownloaded(size int64) {
    49  	m.downloadTemp.Add(size)
    50  	m.downloadTotal.Add(size)
    51  }
    52  
    53  func (m *Manager) Now() (up int64, down int64) {
    54  	return m.uploadBlip.Load(), m.downloadBlip.Load()
    55  }
    56  
    57  func (m *Manager) Snapshot() *Snapshot {
    58  	connections := []tracker{}
    59  	m.connections.Range(func(key, value interface{}) bool {
    60  		connections = append(connections, value.(tracker))
    61  		return true
    62  	})
    63  
    64  	return &Snapshot{
    65  		UploadTotal:   m.uploadTotal.Load(),
    66  		DownloadTotal: m.downloadTotal.Load(),
    67  		Connections:   connections,
    68  	}
    69  }
    70  
    71  func (m *Manager) ResetStatistic() {
    72  	m.uploadTemp.Store(0)
    73  	m.uploadBlip.Store(0)
    74  	m.uploadTotal.Store(0)
    75  	m.downloadTemp.Store(0)
    76  	m.downloadBlip.Store(0)
    77  	m.downloadTotal.Store(0)
    78  }
    79  
    80  func (m *Manager) handle() {
    81  	ticker := time.NewTicker(time.Second)
    82  
    83  	for range ticker.C {
    84  		m.uploadBlip.Store(m.uploadTemp.Load())
    85  		m.uploadTemp.Store(0)
    86  		m.downloadBlip.Store(m.downloadTemp.Load())
    87  		m.downloadTemp.Store(0)
    88  	}
    89  }
    90  
    91  type Snapshot struct {
    92  	DownloadTotal int64     `json:"downloadTotal"`
    93  	UploadTotal   int64     `json:"uploadTotal"`
    94  	Connections   []tracker `json:"connections"`
    95  }