recovery check experiation
This commit is contained in:
30
store.go
30
store.go
@ -20,9 +20,9 @@ type Store struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Node struct {
|
type Node struct {
|
||||||
Value string
|
Value string `json:"value"`
|
||||||
ExpireTime time.Time
|
ExpireTime time.Time `json:"expireTime"`
|
||||||
update chan time.Time
|
update chan time.Time `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Response struct {
|
type Response struct {
|
||||||
@ -151,6 +151,7 @@ func (s *Store) Delete(key string) Response {
|
|||||||
func (s *Store) Save() ([]byte, error) {
|
func (s *Store) Save() ([]byte, error) {
|
||||||
b, err := json.Marshal(s)
|
b, err := json.Marshal(s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return b, nil
|
return b, nil
|
||||||
@ -159,5 +160,26 @@ func (s *Store) Save() ([]byte, error) {
|
|||||||
// recovery the state of the stroage system from a previous state
|
// recovery the state of the stroage system from a previous state
|
||||||
func (s *Store) Recovery(state []byte) error {
|
func (s *Store) Recovery(state []byte) error {
|
||||||
err := json.Unmarshal(state, s)
|
err := json.Unmarshal(state, s)
|
||||||
|
s.clean()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// clean all expired keys
|
||||||
|
func (s *Store) clean() {
|
||||||
|
for key, node := range s.Nodes{
|
||||||
|
// stable node
|
||||||
|
if node.ExpireTime.Equal(time.Unix(0,0)) {
|
||||||
|
continue
|
||||||
|
} else {
|
||||||
|
if node.ExpireTime.Sub(time.Now()) >= time.Second {
|
||||||
|
node.update = make(chan time.Time)
|
||||||
|
go s.expire(key, node.update, node.ExpireTime)
|
||||||
|
} else {
|
||||||
|
// we should delete this node
|
||||||
|
delete(s.Nodes, key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ func TestStoreGet(t *testing.T) {
|
|||||||
func TestSaveAndRecovery(t *testing.T) {
|
func TestSaveAndRecovery(t *testing.T) {
|
||||||
|
|
||||||
s.Set("foo", "bar", time.Unix(0, 0))
|
s.Set("foo", "bar", time.Unix(0, 0))
|
||||||
|
s.Set("foo2", "bar2", time.Now().Add(time.Second * 5))
|
||||||
state, err := s.Save()
|
state, err := s.Save()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -35,6 +35,10 @@ func TestSaveAndRecovery(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
newStore := createStore()
|
newStore := createStore()
|
||||||
|
|
||||||
|
// wait for foo2 expires
|
||||||
|
time.Sleep(time.Second * 6)
|
||||||
|
|
||||||
newStore.Recovery(state)
|
newStore.Recovery(state)
|
||||||
|
|
||||||
res := newStore.Get("foo")
|
res := newStore.Get("foo")
|
||||||
@ -42,6 +46,14 @@ func TestSaveAndRecovery(t *testing.T) {
|
|||||||
if res.OldValue != "bar" {
|
if res.OldValue != "bar" {
|
||||||
t.Fatalf("Cannot recovery")
|
t.Fatalf("Cannot recovery")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
res = newStore.Get("foo2")
|
||||||
|
|
||||||
|
if res.Exist {
|
||||||
|
t.Fatalf("Get expired value")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
s.Delete("foo")
|
s.Delete("foo")
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user