ssm-api: Fix save cache

This commit is contained in:
世界
2025-11-04 10:59:18 +08:00
parent 63c8207d7a
commit 5841d410a1
2 changed files with 57 additions and 10 deletions

View File

@@ -49,6 +49,9 @@ func (s *Service) loadCache() error {
os.RemoveAll(basePath) os.RemoveAll(basePath)
return err return err
} }
s.cacheMutex.Lock()
s.lastSavedCache = cacheBinary
s.cacheMutex.Unlock()
return nil return nil
} }
@@ -56,16 +59,30 @@ func (s *Service) saveCache() error {
if s.cachePath == "" { if s.cachePath == "" {
return nil return nil
} }
cacheBinary, err := s.encodeCache()
if err != nil {
return err
}
s.cacheMutex.Lock()
defer s.cacheMutex.Unlock()
if bytes.Equal(s.lastSavedCache, cacheBinary) {
return nil
}
return s.writeCache(cacheBinary)
}
func (s *Service) writeCache(cacheBinary []byte) error {
basePath := filemanager.BasePath(s.ctx, s.cachePath) basePath := filemanager.BasePath(s.ctx, s.cachePath)
err := os.MkdirAll(filepath.Dir(basePath), 0o777) err := os.MkdirAll(filepath.Dir(basePath), 0o777)
if err != nil { if err != nil {
return err return err
} }
cacheBinary, err := s.encodeCache() err = os.WriteFile(basePath, cacheBinary, 0o644)
if err != nil { if err != nil {
return err return err
} }
return os.WriteFile(s.cachePath, cacheBinary, 0o644) s.lastSavedCache = cacheBinary
return nil
} }
func (s *Service) decodeCache(cacheBinary []byte) error { func (s *Service) decodeCache(cacheBinary []byte) error {

View File

@@ -4,6 +4,8 @@ import (
"context" "context"
"errors" "errors"
"net/http" "net/http"
"sync"
"time"
"github.com/sagernet/sing-box/adapter" "github.com/sagernet/sing-box/adapter"
boxService "github.com/sagernet/sing-box/adapter/service" boxService "github.com/sagernet/sing-box/adapter/service"
@@ -28,21 +30,27 @@ func RegisterService(registry *boxService.Registry) {
type Service struct { type Service struct {
boxService.Adapter boxService.Adapter
ctx context.Context ctx context.Context
logger log.ContextLogger cancel context.CancelFunc
listener *listener.Listener logger log.ContextLogger
tlsConfig tls.ServerConfig listener *listener.Listener
httpServer *http.Server tlsConfig tls.ServerConfig
traffics map[string]*TrafficManager httpServer *http.Server
users map[string]*UserManager traffics map[string]*TrafficManager
cachePath string users map[string]*UserManager
cachePath string
saveTicker *time.Ticker
lastSavedCache []byte
cacheMutex sync.Mutex
} }
func NewService(ctx context.Context, logger log.ContextLogger, tag string, options option.SSMAPIServiceOptions) (adapter.Service, error) { func NewService(ctx context.Context, logger log.ContextLogger, tag string, options option.SSMAPIServiceOptions) (adapter.Service, error) {
ctx, cancel := context.WithCancel(ctx)
chiRouter := chi.NewRouter() chiRouter := chi.NewRouter()
s := &Service{ s := &Service{
Adapter: boxService.NewAdapter(C.TypeSSMAPI, tag), Adapter: boxService.NewAdapter(C.TypeSSMAPI, tag),
ctx: ctx, ctx: ctx,
cancel: cancel,
logger: logger, logger: logger,
listener: listener.New(listener.Options{ listener: listener.New(listener.Options{
Context: ctx, Context: ctx,
@@ -95,6 +103,8 @@ func (s *Service) Start(stage adapter.StartStage) error {
if err != nil { if err != nil {
s.logger.Error(E.Cause(err, "load cache")) s.logger.Error(E.Cause(err, "load cache"))
} }
s.saveTicker = time.NewTicker(1 * time.Minute)
go s.loopSaveCache()
if s.tlsConfig != nil { if s.tlsConfig != nil {
err = s.tlsConfig.Start() err = s.tlsConfig.Start()
if err != nil { if err != nil {
@@ -120,7 +130,27 @@ func (s *Service) Start(stage adapter.StartStage) error {
return nil return nil
} }
func (s *Service) loopSaveCache() {
for {
select {
case <-s.ctx.Done():
return
case <-s.saveTicker.C:
err := s.saveCache()
if err != nil {
s.logger.Error(E.Cause(err, "save cache"))
}
}
}
}
func (s *Service) Close() error { func (s *Service) Close() error {
if s.cancel != nil {
s.cancel()
}
if s.saveTicker != nil {
s.saveTicker.Stop()
}
err := s.saveCache() err := s.saveCache()
if err != nil { if err != nil {
s.logger.Error(E.Cause(err, "save cache")) s.logger.Error(E.Cause(err, "save cache"))