-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
132 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
package platform | ||
|
||
import ( | ||
"errors" | ||
"time" | ||
) | ||
|
||
type cache struct { | ||
cleanupInterval time.Duration | ||
expiresAt time.Time | ||
item any | ||
} | ||
|
||
func newCache(cleanupInterval time.Duration) *cache { | ||
c := &cache{ | ||
cleanupInterval: cleanupInterval, | ||
} | ||
go c.startCleanup() | ||
|
||
return c | ||
} | ||
|
||
func (c *cache) set(item any, expiresAt time.Time) error { | ||
if item == nil { | ||
return errors.New("item is not set") | ||
} | ||
if expiresAt.IsZero() { | ||
return errors.New("expiresAt is not set") | ||
} | ||
|
||
c.item = item | ||
c.expiresAt = expiresAt | ||
|
||
return nil | ||
} | ||
|
||
func (c *cache) get() any { | ||
if time.Now().After(c.expiresAt) { | ||
return nil | ||
} | ||
|
||
return c.item | ||
} | ||
|
||
func (c *cache) clear() { | ||
c.item = nil | ||
c.expiresAt = time.Time{} | ||
} | ||
|
||
func (c *cache) startCleanup() { | ||
t := time.NewTicker(c.cleanupInterval) | ||
defer t.Stop() | ||
|
||
for { | ||
<-t.C | ||
if !c.expiresAt.IsZero() && time.Now().After(c.expiresAt) { | ||
c.clear() | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
package platform | ||
|
||
import ( | ||
"testing" | ||
"time" | ||
) | ||
|
||
func TestNewCache(t *testing.T) { | ||
cleanupInterval := 10 * time.Minute | ||
cache := newCache(cleanupInterval) | ||
if cache.cleanupInterval != cleanupInterval { | ||
t.Errorf("expected cleanupInterval %v, got %v", cleanupInterval, cache.cleanupInterval) | ||
} | ||
} | ||
|
||
func TestCache_Set(t *testing.T) { | ||
cleanupInterval := 10 * time.Minute | ||
cache := newCache(cleanupInterval) | ||
|
||
item := "dummy_item" | ||
expiresAt := time.Now().Add(1 * time.Hour) | ||
err := cache.set(item, expiresAt) | ||
if err != nil { | ||
t.Error(err) | ||
} | ||
if cache.item != item { | ||
t.Errorf("item %v, got %v", item, cache.item) | ||
} | ||
if cache.expiresAt != expiresAt { | ||
t.Errorf("expiresAt %v, got %v", expiresAt, cache.expiresAt) | ||
} | ||
} | ||
|
||
func TestCache_Get_ItemNotExpired(t *testing.T) { | ||
cleanupInterval := 10 * time.Minute | ||
cache := newCache(cleanupInterval) | ||
|
||
item := "dummy_item" | ||
expiresAt := time.Now().Add(1 * time.Hour) | ||
err := cache.set(item, expiresAt) | ||
if err != nil { | ||
t.Error(err) | ||
} | ||
|
||
cachedItem := cache.get() | ||
if cachedItem != item { | ||
t.Errorf("cachedItem %v, got %v", item, cachedItem) | ||
} | ||
} | ||
|
||
func TestCache_Get_ItemExpired(t *testing.T) { | ||
cleanupInterval := 1 * time.Second | ||
cache := newCache(cleanupInterval) | ||
|
||
item := "dummy_item" | ||
expiresAt := time.Now().Add(1 * time.Second) | ||
err := cache.set(item, expiresAt) | ||
if err != nil { | ||
t.Error(err) | ||
} | ||
|
||
// キャッシュの期限切れと削除が行われるのを待つ | ||
time.Sleep(2 * time.Second) | ||
|
||
cachedItem := cache.get() | ||
if cachedItem != nil { | ||
t.Errorf("cached item not cleared, got %v", cachedItem) | ||
} | ||
if !cache.expiresAt.IsZero() { | ||
t.Errorf("expiresAt not cleared, got %v", cache.expiresAt) | ||
} | ||
} |