mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-09-30 06:16:37 +08:00
160e63558f
Honest TTL cleanup semantics; enqueue-safe dedup with flush retry and writer metrics; model insert hooks; latest-per-node and hourly metric/openresty rollups; small-host pool/async defaults, traffic hourly TTL, and UV labeling.
66 lines
1.2 KiB
Go
66 lines
1.2 KiB
Go
// Copyright 2026 Arctel.net
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
package chwriter
|
|
|
|
import (
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
const dedupTTL = 2 * time.Minute
|
|
|
|
type dedupSet struct {
|
|
mu sync.Mutex
|
|
keys map[string]time.Time
|
|
lastCleanup time.Time
|
|
}
|
|
|
|
func newDedupSet() *dedupSet {
|
|
return &dedupSet{
|
|
keys: make(map[string]time.Time),
|
|
lastCleanup: time.Now(),
|
|
}
|
|
}
|
|
|
|
// markIfNew records key when it has not been seen within dedupTTL.
|
|
func (s *dedupSet) markIfNew(key string) bool {
|
|
if s == nil || key == "" {
|
|
return false
|
|
}
|
|
|
|
now := time.Now()
|
|
s.mu.Lock()
|
|
defer s.mu.Unlock()
|
|
|
|
s.cleanupExpiredLocked(now)
|
|
|
|
if expiresAt, exists := s.keys[key]; exists && now.Before(expiresAt) {
|
|
return false
|
|
}
|
|
s.keys[key] = now.Add(dedupTTL)
|
|
return true
|
|
}
|
|
|
|
// unmark removes a key so a later enqueue or flush retry may accept it again.
|
|
func (s *dedupSet) unmark(key string) {
|
|
if s == nil || key == "" {
|
|
return
|
|
}
|
|
s.mu.Lock()
|
|
defer s.mu.Unlock()
|
|
delete(s.keys, key)
|
|
}
|
|
|
|
func (s *dedupSet) cleanupExpiredLocked(now time.Time) {
|
|
if now.Sub(s.lastCleanup) < 30*time.Second {
|
|
return
|
|
}
|
|
for existing, expiresAt := range s.keys {
|
|
if now.After(expiresAt) {
|
|
delete(s.keys, existing)
|
|
}
|
|
}
|
|
s.lastCleanup = now
|
|
}
|