mirror of
https://github.com/TecharoHQ/anubis.git
synced 2025-10-04 05:41:59 +08:00
* fix(decaymap): fix lock convoy Ref #1103 This uses the actor pattern to delay deletion instead of making things fight over a lock. It also properly fixes locking logic to prevent the convoy problem. Signed-off-by: Xe Iaso <me@xeiaso.net> * docs: update CHANGELOG Signed-off-by: Xe Iaso <me@xeiaso.net> --------- Signed-off-by: Xe Iaso <me@xeiaso.net>
75 lines
1.7 KiB
Go
75 lines
1.7 KiB
Go
package decaymap
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestImpl(t *testing.T) {
|
|
dm := New[string, string]()
|
|
t.Cleanup(dm.Close)
|
|
|
|
dm.Set("test", "hi", 5*time.Minute)
|
|
|
|
val, ok := dm.Get("test")
|
|
if !ok {
|
|
t.Error("somehow the test key was not set")
|
|
}
|
|
|
|
if val != "hi" {
|
|
t.Errorf("wanted value %q, got: %q", "hi", val)
|
|
}
|
|
|
|
ok = dm.expire("test")
|
|
if !ok {
|
|
t.Error("somehow could not force-expire the test key")
|
|
}
|
|
|
|
_, ok = dm.Get("test")
|
|
if ok {
|
|
t.Error("got value even though it was supposed to be expired")
|
|
}
|
|
|
|
// Deletion of expired entries after Get is deferred to a background worker.
|
|
// Assert it eventually disappears from the map.
|
|
deadline := time.Now().Add(200 * time.Millisecond)
|
|
for time.Now().Before(deadline) {
|
|
if dm.Len() == 0 {
|
|
break
|
|
}
|
|
time.Sleep(5 * time.Millisecond)
|
|
}
|
|
if dm.Len() != 0 {
|
|
t.Fatalf("expected background cleanup to remove expired key; len=%d", dm.Len())
|
|
}
|
|
}
|
|
|
|
func TestCleanup(t *testing.T) {
|
|
dm := New[string, string]()
|
|
t.Cleanup(dm.Close)
|
|
|
|
dm.Set("test1", "hi1", 1*time.Second)
|
|
dm.Set("test2", "hi2", 2*time.Second)
|
|
dm.Set("test3", "hi3", 3*time.Second)
|
|
|
|
dm.expire("test1") // Force expire test1
|
|
dm.expire("test2") // Force expire test2
|
|
|
|
dm.Cleanup()
|
|
|
|
finalLen := dm.Len() // Get the length after cleanup
|
|
|
|
if finalLen != 1 { // "test3" should be the only one left
|
|
t.Errorf("Cleanup failed to remove expired entries. Expected length 1, got %d", finalLen)
|
|
}
|
|
|
|
if _, ok := dm.Get("test1"); ok { // Verify Get still behaves correctly after Cleanup
|
|
t.Error("test1 should not be found after cleanup")
|
|
}
|
|
if _, ok := dm.Get("test2"); ok {
|
|
t.Error("test2 should not be found after cleanup")
|
|
}
|
|
if val, ok := dm.Get("test3"); !ok || val != "hi3" {
|
|
t.Error("test3 should still be found after cleanup")
|
|
}
|
|
}
|