1
0

manager.go 2.3 KB

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