sing-box/experimental/clashapi/trafficontrol/manager.go

125 lines
2.7 KiB
Go
Raw Normal View History

2022-07-22 09:29:13 +08:00
package trafficontrol
2022-07-19 22:16:49 +08:00
import (
2023-04-11 16:43:45 +08:00
"runtime"
2022-07-19 22:16:49 +08:00
"time"
"github.com/sagernet/sing-box/experimental/clashapi/compatible"
2023-04-14 20:55:05 +08:00
"github.com/sagernet/sing/common/atomic"
2022-07-19 22:16:49 +08:00
)
type Manager struct {
2023-04-14 20:55:05 +08:00
uploadTemp atomic.Int64
downloadTemp atomic.Int64
uploadBlip atomic.Int64
downloadBlip atomic.Int64
uploadTotal atomic.Int64
downloadTotal atomic.Int64
connections compatible.Map[string, tracker]
ticker *time.Ticker
done chan struct{}
2023-04-11 16:43:45 +08:00
// process *process.Process
memory uint64
2022-07-19 22:16:49 +08:00
}
func NewManager() *Manager {
manager := &Manager{
2023-04-14 20:55:05 +08:00
ticker: time.NewTicker(time.Second),
done: make(chan struct{}),
2023-04-11 16:43:45 +08:00
// process: &process.Process{Pid: int32(os.Getpid())},
2022-07-19 22:16:49 +08:00
}
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()
}
2023-07-16 14:08:45 +08:00
func (m *Manager) Total() (up int64, down int64) {
return m.uploadTotal.Load(), m.downloadTotal.Load()
}
func (m *Manager) Connections() int {
return m.connections.Len()
}
2022-07-19 22:16:49 +08:00
func (m *Manager) Snapshot() *Snapshot {
2022-07-30 14:50:33 +08:00
var connections []tracker
2022-07-19 22:16:49 +08:00
m.connections.Range(func(_ string, value tracker) bool {
connections = append(connections, value)
return true
})
2023-04-11 16:43:45 +08:00
//if memoryInfo, err := m.process.MemoryInfo(); err == nil {
// m.memory = memoryInfo.RSS
//} else {
var memStats runtime.MemStats
runtime.ReadMemStats(&memStats)
m.memory = memStats.StackInuse + memStats.HeapInuse + memStats.HeapIdle - memStats.HeapReleased
2022-07-19 22:16:49 +08:00
return &Snapshot{
UploadTotal: m.uploadTotal.Load(),
DownloadTotal: m.downloadTotal.Load(),
Connections: connections,
2023-04-11 16:43:45 +08:00
Memory: m.memory,
2022-07-19 22:16:49 +08:00
}
}
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() {
2022-08-02 18:47:23 +08:00
var uploadTemp int64
var downloadTemp int64
2022-07-30 14:50:33 +08:00
for {
select {
case <-m.done:
return
case <-m.ticker.C:
}
2022-08-02 18:47:23 +08:00
uploadTemp = m.uploadTemp.Swap(0)
downloadTemp = m.downloadTemp.Swap(0)
m.uploadBlip.Store(uploadTemp)
m.downloadBlip.Store(downloadTemp)
2022-07-19 22:16:49 +08:00
}
}
2022-07-30 14:50:33 +08:00
func (m *Manager) Close() error {
m.ticker.Stop()
close(m.done)
return nil
}
2022-07-19 22:16:49 +08:00
type Snapshot struct {
DownloadTotal int64 `json:"downloadTotal"`
UploadTotal int64 `json:"uploadTotal"`
Connections []tracker `json:"connections"`
2023-04-11 16:43:45 +08:00
Memory uint64 `json:"memory"`
2022-07-19 22:16:49 +08:00
}