123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109 |
- package trafficontrol
- import (
- "time"
- "github.com/sagernet/sing-box/experimental/clashapi/compatible"
- "go.uber.org/atomic"
- )
- type Manager struct {
- connections compatible.Map[string, tracker]
- uploadTemp *atomic.Int64
- downloadTemp *atomic.Int64
- uploadBlip *atomic.Int64
- downloadBlip *atomic.Int64
- uploadTotal *atomic.Int64
- downloadTotal *atomic.Int64
- ticker *time.Ticker
- done chan struct{}
- }
- func NewManager() *Manager {
- manager := &Manager{
- uploadTemp: atomic.NewInt64(0),
- downloadTemp: atomic.NewInt64(0),
- uploadBlip: atomic.NewInt64(0),
- downloadBlip: atomic.NewInt64(0),
- uploadTotal: atomic.NewInt64(0),
- downloadTotal: atomic.NewInt64(0),
- ticker: time.NewTicker(time.Second),
- done: make(chan struct{}),
- }
- go manager.handle()
- return manager
- }
- func (m *Manager) Join(c tracker) {
- m.connections.Store(c.ID(), c)
- }
- func (m *Manager) Leave(c tracker) {
- m.connections.Delete(c.ID())
- }
- func (m *Manager) PushUploaded(size int64) {
- m.uploadTemp.Add(size)
- m.uploadTotal.Add(size)
- }
- func (m *Manager) PushDownloaded(size int64) {
- m.downloadTemp.Add(size)
- m.downloadTotal.Add(size)
- }
- func (m *Manager) Now() (up int64, down int64) {
- return m.uploadBlip.Load(), m.downloadBlip.Load()
- }
- func (m *Manager) Snapshot() *Snapshot {
- var connections []tracker
- m.connections.Range(func(_ string, value tracker) bool {
- connections = append(connections, value)
- return true
- })
- return &Snapshot{
- UploadTotal: m.uploadTotal.Load(),
- DownloadTotal: m.downloadTotal.Load(),
- Connections: connections,
- }
- }
- func (m *Manager) ResetStatistic() {
- m.uploadTemp.Store(0)
- m.uploadBlip.Store(0)
- m.uploadTotal.Store(0)
- m.downloadTemp.Store(0)
- m.downloadBlip.Store(0)
- m.downloadTotal.Store(0)
- }
- func (m *Manager) handle() {
- var uploadTemp int64
- var downloadTemp int64
- for {
- select {
- case <-m.done:
- return
- case <-m.ticker.C:
- }
- uploadTemp = m.uploadTemp.Swap(0)
- downloadTemp = m.downloadTemp.Swap(0)
- m.uploadBlip.Store(uploadTemp)
- m.downloadBlip.Store(downloadTemp)
- }
- }
- func (m *Manager) Close() error {
- m.ticker.Stop()
- close(m.done)
- return nil
- }
- type Snapshot struct {
- DownloadTotal int64 `json:"downloadTotal"`
- UploadTotal int64 `json:"uploadTotal"`
- Connections []tracker `json:"connections"`
- }
|