diff --git a/adapter/fakeip.go b/adapter/fakeip.go index 6a142245..51247c32 100644 --- a/adapter/fakeip.go +++ b/adapter/fakeip.go @@ -18,6 +18,7 @@ type FakeIPStore interface { type FakeIPStorage interface { FakeIPMetadata() *FakeIPMetadata FakeIPSaveMetadata(metadata *FakeIPMetadata) error + FakeIPSaveMetadataAsync(metadata *FakeIPMetadata) FakeIPStore(address netip.Addr, domain string) error FakeIPStoreAsync(address netip.Addr, domain string, logger logger.Logger) FakeIPLoad(address netip.Addr) (string, bool) diff --git a/experimental/clashapi/cachefile/cache.go b/experimental/clashapi/cachefile/cache.go index c282d715..561ae0a9 100644 --- a/experimental/clashapi/cachefile/cache.go +++ b/experimental/clashapi/cachefile/cache.go @@ -17,12 +17,13 @@ var bucketSelected = []byte("selected") var _ adapter.ClashCacheFile = (*CacheFile)(nil) type CacheFile struct { - DB *bbolt.DB - cacheID []byte - saveAccess sync.RWMutex - saveDomain map[netip.Addr]string - saveAddress4 map[string]netip.Addr - saveAddress6 map[string]netip.Addr + DB *bbolt.DB + cacheID []byte + saveAccess sync.RWMutex + saveDomain map[netip.Addr]string + saveAddress4 map[string]netip.Addr + saveAddress6 map[string]netip.Addr + saveMetadataTimer *time.Timer } func Open(path string, cacheID string) (*CacheFile, error) { diff --git a/experimental/clashapi/cachefile/fakeip.go b/experimental/clashapi/cachefile/fakeip.go index cdc279f5..a2396b59 100644 --- a/experimental/clashapi/cachefile/fakeip.go +++ b/experimental/clashapi/cachefile/fakeip.go @@ -3,6 +3,7 @@ package cachefile import ( "net/netip" "os" + "time" "github.com/sagernet/sing-box/adapter" "github.com/sagernet/sing/common/logger" @@ -57,6 +58,15 @@ func (c *CacheFile) FakeIPSaveMetadata(metadata *adapter.FakeIPMetadata) error { }) } +func (c *CacheFile) FakeIPSaveMetadataAsync(metadata *adapter.FakeIPMetadata) { + if timer := c.saveMetadataTimer; timer != nil { + timer.Stop() + } + c.saveMetadataTimer = time.AfterFunc(10*time.Second, func() { + _ = c.FakeIPSaveMetadata(metadata) + }) +} + func (c *CacheFile) FakeIPStore(address netip.Addr, domain string) error { return c.DB.Batch(func(tx *bbolt.Tx) error { bucket, err := tx.CreateBucketIfNotExists(bucketFakeIP) diff --git a/transport/fakeip/memory.go b/transport/fakeip/memory.go index b9e6a999..0bca4910 100644 --- a/transport/fakeip/memory.go +++ b/transport/fakeip/memory.go @@ -34,6 +34,9 @@ func (s *MemoryStorage) FakeIPSaveMetadata(metadata *adapter.FakeIPMetadata) err return nil } +func (s *MemoryStorage) FakeIPSaveMetadataAsync(metadata *adapter.FakeIPMetadata) { +} + func (s *MemoryStorage) FakeIPStore(address netip.Addr, domain string) error { s.addressAccess.Lock() s.domainAccess.Lock() diff --git a/transport/fakeip/store.go b/transport/fakeip/store.go index 7571161c..96f6bf03 100644 --- a/transport/fakeip/store.go +++ b/transport/fakeip/store.go @@ -99,6 +99,12 @@ func (s *Store) Create(domain string, isIPv6 bool) (netip.Addr, error) { address = nextAddress } s.storage.FakeIPStoreAsync(address, domain, s.logger) + s.storage.FakeIPSaveMetadataAsync(&adapter.FakeIPMetadata{ + Inet4Range: s.inet4Range, + Inet6Range: s.inet6Range, + Inet4Current: s.inet4Current, + Inet6Current: s.inet6Current, + }) return address, nil }