From e6379625c5f9b72df5ba04ada5b776ba01013b27 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E4=B8=96=E7=95=8C?= <i@sekai.icu>
Date: Wed, 27 Nov 2024 18:05:30 +0800
Subject: [PATCH] clashapi: Remove traffic loop

---
 experimental/clashapi/server.go               | 16 ++++---
 .../clashapi/trafficontrol/manager.go         | 46 +------------------
 experimental/libbox/command_status.go         | 15 +++++-
 3 files changed, 24 insertions(+), 53 deletions(-)

diff --git a/experimental/clashapi/server.go b/experimental/clashapi/server.go
index b0f47646..db8e2860 100644
--- a/experimental/clashapi/server.go
+++ b/experimental/clashapi/server.go
@@ -321,27 +321,31 @@ func traffic(trafficManager *trafficontrol.Manager) func(w http.ResponseWriter,
 		tick := time.NewTicker(time.Second)
 		defer tick.Stop()
 		buf := &bytes.Buffer{}
-		var err error
+		var (
+			upTotal   int64
+			downTotal int64
+			err       error
+		)
 		for range tick.C {
 			buf.Reset()
-			up, down := trafficManager.Now()
+			upTotalNew, downTotalNew := trafficManager.Total()
 			if err := json.NewEncoder(buf).Encode(Traffic{
-				Up:   up,
-				Down: down,
+				Up:   upTotalNew - upTotal,
+				Down: downTotalNew - downTotal,
 			}); err != nil {
 				break
 			}
-
 			if conn == nil {
 				_, err = w.Write(buf.Bytes())
 				w.(http.Flusher).Flush()
 			} else {
 				err = wsutil.WriteServerText(conn, buf.Bytes())
 			}
-
 			if err != nil {
 				break
 			}
+			upTotal = upTotalNew
+			downTotal = downTotalNew
 		}
 	}
 }
diff --git a/experimental/clashapi/trafficontrol/manager.go b/experimental/clashapi/trafficontrol/manager.go
index 9b22f1e3..757ffdf9 100644
--- a/experimental/clashapi/trafficontrol/manager.go
+++ b/experimental/clashapi/trafficontrol/manager.go
@@ -16,30 +16,18 @@ import (
 )
 
 type Manager struct {
-	uploadTemp    atomic.Int64
-	downloadTemp  atomic.Int64
-	uploadBlip    atomic.Int64
-	downloadBlip  atomic.Int64
 	uploadTotal   atomic.Int64
 	downloadTotal atomic.Int64
 
 	connections             compatible.Map[uuid.UUID, Tracker]
 	closedConnectionsAccess sync.Mutex
 	closedConnections       list.List[TrackerMetadata]
-	ticker                  *time.Ticker
-	done                    chan struct{}
 	// process     *process.Process
 	memory uint64
 }
 
 func NewManager() *Manager {
-	manager := &Manager{
-		ticker: time.NewTicker(time.Second),
-		done:   make(chan struct{}),
-		// process: &process.Process{Pid: int32(os.Getpid())},
-	}
-	go manager.handle()
-	return manager
+	return &Manager{}
 }
 
 func (m *Manager) Join(c Tracker) {
@@ -61,19 +49,13 @@ func (m *Manager) Leave(c Tracker) {
 }
 
 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) Total() (up int64, down int64) {
 	return m.uploadTotal.Load(), m.downloadTotal.Load()
 }
@@ -127,36 +109,10 @@ func (m *Manager) Snapshot() *Snapshot {
 }
 
 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 {
 	Download    int64
 	Upload      int64
diff --git a/experimental/libbox/command_status.go b/experimental/libbox/command_status.go
index 810b3dce..05c9582a 100644
--- a/experimental/libbox/command_status.go
+++ b/experimental/libbox/command_status.go
@@ -33,7 +33,6 @@ func (s *CommandServer) readStatus() StatusMessage {
 	if s.service != nil {
 		message.TrafficAvailable = true
 		trafficManager := s.service.clashServer.(*clashapi.Server).TrafficManager()
-		message.Uplink, message.Downlink = trafficManager.Now()
 		message.UplinkTotal, message.DownlinkTotal = trafficManager.Total()
 		message.ConnectionsIn = int32(trafficManager.ConnectionsLen())
 	}
@@ -50,8 +49,20 @@ func (s *CommandServer) handleStatusConn(conn net.Conn) error {
 	ticker := time.NewTicker(time.Duration(interval))
 	defer ticker.Stop()
 	ctx := connKeepAlive(conn)
+	var (
+		status        StatusMessage
+		uploadTotal   int64
+		downloadTotal int64
+	)
 	for {
-		err = binary.Write(conn, binary.BigEndian, s.readStatus())
+		status = s.readStatus()
+		upload := status.UplinkTotal - uploadTotal
+		download := status.DownlinkTotal - downloadTotal
+		uploadTotal = status.UplinkTotal
+		downloadTotal = status.DownlinkTotal
+		status.Uplink = upload
+		status.Downlink = download
+		err = binary.Write(conn, binary.BigEndian, status)
 		if err != nil {
 			return err
 		}