mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-11-15 00:09:00 +01:00
fix(mount): prevent negative activity-score shifts (#12631)
fix(mount): bound activity decay shifts across time regressions
This commit is contained in:
1 parent
0a38738076
commit
65ecb6aa12
2 files changed
+43
-3
No files matched your search
@@ -17,7 +17,8 @@ func NewActivityScore() *ActivityScore {
|
||||
func (as *ActivityScore) MarkRead() {
|
||||
now := time.Now().UnixNano()
|
||||
last := atomic.SwapInt64(&as.lastActiveTsNs, now)
|
||||
deltaTime := (now - last) >> 30 // about number of seconds
|
||||
// Concurrent timestamp swaps or a clock adjustment can make last newer than now.
|
||||
deltaTime := max(0, min(63, (now-last)>>30)) // about number of seconds
|
||||
for {
|
||||
old := atomic.LoadInt64(&as.decayedActivenessScore)
|
||||
score := old>>deltaTime + 256
|
||||
@@ -33,7 +34,7 @@ func (as *ActivityScore) MarkRead() {
|
||||
func (as *ActivityScore) MarkWrite() {
|
||||
now := time.Now().UnixNano()
|
||||
last := atomic.SwapInt64(&as.lastActiveTsNs, now)
|
||||
deltaTime := (now - last) >> 30 // about number of seconds
|
||||
deltaTime := max(0, min(63, (now-last)>>30)) // about number of seconds
|
||||
for {
|
||||
old := atomic.LoadInt64(&as.decayedActivenessScore)
|
||||
score := old>>deltaTime + 1024
|
||||
@@ -47,6 +48,6 @@ func (as *ActivityScore) MarkWrite() {
|
||||
}
|
||||
|
||||
func (as *ActivityScore) ActivityScore() int64 {
|
||||
deltaTime := (time.Now().UnixNano() - atomic.LoadInt64(&as.lastActiveTsNs)) >> 30
|
||||
deltaTime := max(0, min(63, (time.Now().UnixNano()-atomic.LoadInt64(&as.lastActiveTsNs))>>30))
|
||||
return atomic.LoadInt64(&as.decayedActivenessScore) >> deltaTime
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package page_writer
|
||||
|
||||
import (
|
||||
"sync/atomic"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestActivityScoreHandlesFutureTimestamp(t *testing.T) {
|
||||
for _, test := range []struct {
|
||||
name string
|
||||
call func(*ActivityScore) int64
|
||||
want int64
|
||||
}{
|
||||
{"MarkRead", func(score *ActivityScore) int64 {
|
||||
score.MarkRead()
|
||||
return score.ActivityScore()
|
||||
}, 4352},
|
||||
{"MarkWrite", func(score *ActivityScore) int64 {
|
||||
score.MarkWrite()
|
||||
return score.ActivityScore()
|
||||
}, 5120},
|
||||
{"ActivityScore", (*ActivityScore).ActivityScore, 4096},
|
||||
} {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
score := NewActivityScore()
|
||||
atomic.StoreInt64(&score.lastActiveTsNs, time.Now().Add(time.Hour).UnixNano())
|
||||
atomic.StoreInt64(&score.decayedActivenessScore, 4096)
|
||||
defer func() {
|
||||
if caught := recover(); caught != nil {
|
||||
t.Fatalf("future last-active timestamp must not panic: %v", caught)
|
||||
}
|
||||
}()
|
||||
if got := test.call(score); got != test.want {
|
||||
t.Fatalf("score=%d, want %d without backwards-time decay", got, test.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user