-
Notifications
You must be signed in to change notification settings - Fork 0
/
pruner.go
68 lines (64 loc) · 2.1 KB
/
pruner.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
// Copyright 2016 George S. Kong. All rights reserved.
// Use of this source code is governed by a license that can be found in the LICENSE.txt file.
package qsldb
import (
"bytes"
"fmt"
"io"
"time"
)
// prune periodically deletes expired sessions from the session store.
// It uses an index, to locate expired sessions efficiently.
//
// prune runs in a goroutine, started by NewGldbStore.
// It runs until it receives something on its pruneKill channel.
// You can change its wait interval by sending a number of seconds
// to its pruneInterval channel.
func (gst *gldbStore) prune(waitSecs int, pruneInterval <-chan int, pruneKill <-chan int, log io.Writer) {
for {
select {
case waitSecs = <-pruneInterval:
case <-pruneKill:
return
case <-time.After(time.Duration(waitSecs) * time.Second):
}
now := time.Now().Unix()
iter := gst.db.NewIterator(nil, nil)
// Giving Seek the key prefix brings us to the first record of the
// expiration index, which is ordered by expiration time (ascending).
for ok := iter.Seek(gst.expPrefix); ok; ok = iter.Next() {
eKey := gldbExpKey(iter.Key())
if bytes.Compare(eKey[:gst.prefixSize], gst.expPrefix) != 0 {
// we're past the last session expiration index record
break
}
if len(eKey) != gst.expKeySize {
if log != nil {
fmt.Fprintf(log, "qsess.Store.prune - pruning malformed expKey - %x", eKey)
}
gst.db.Delete(eKey, nil)
continue
}
if eKey.expiration(gst.prefixSize) >= now {
// we're past the records of interest
break
}
// Current eKey's expiration time is in the past.
// Read the session record and verify it's really expired,
// then delete the session record and index record.
// Ignore deletion failures, since other concurrent code can
// delete these records.
sessKey := eKey.sessKey(gst.prefixSize)
data, err := gst.db.Get(sessKey, nil)
if err == nil {
sessData := gldbSessValue(data)
if sessData.expiration() < now {
gst.db.Delete(gst.uidKey(sessData.userID(), sessKey), nil)
gst.db.Delete(sessKey, nil)
}
}
gst.db.Delete(eKey, nil)
}
iter.Release()
}
}