Allow configuration of tidy functions. Use a closure to decide what entries
to delete. The closure takes a *bolt.Bucket and returns an integer of the number of entries deleted.
This commit is contained in:
parent
d6f4920507
commit
17beaca380
77
persist.go
77
persist.go
|
@ -40,23 +40,41 @@ type Config struct {
|
|||
configured bool
|
||||
MaxVars int
|
||||
DBPath string
|
||||
Tidy TidyConfig
|
||||
}
|
||||
|
||||
func Init(x ...Config) {
|
||||
mux.Lock()
|
||||
c := Config{MaxVars: 64, DBPath: "db"} // default config
|
||||
c := Config {
|
||||
configured: true,
|
||||
MaxVars: 64, // default config
|
||||
DBPath: "db",
|
||||
}
|
||||
conf = c
|
||||
if len(x) > 0 {
|
||||
c = x[0]
|
||||
}
|
||||
if c.MaxVars != 0 {
|
||||
conf.MaxVars = c.MaxVars
|
||||
conf.configured = true
|
||||
}
|
||||
if c.DBPath != "" {
|
||||
conf.DBPath = c.DBPath
|
||||
conf.configured = true
|
||||
}
|
||||
|
||||
if c.Tidy.Interval == 0 {
|
||||
conf.Tidy.Interval = 10 * time.Second
|
||||
} else {
|
||||
fmt.Println("Setting conf.Tidy.Interval to",c.Tidy.Interval)
|
||||
conf.Tidy.Interval = c.Tidy.Interval
|
||||
}
|
||||
|
||||
if c.Tidy.Func == nil {
|
||||
conf.Tidy.Func = ExpireAfter(24 * time.Hour)
|
||||
} else {
|
||||
fmt.Println("Setting conf.Tidy.Func")
|
||||
conf.Tidy.Func = c.Tidy.Func
|
||||
}
|
||||
|
||||
mux.Unlock()
|
||||
}
|
||||
|
||||
|
@ -274,7 +292,9 @@ func start() {
|
|||
launched = true
|
||||
|
||||
if conf.configured == false {
|
||||
mux.Unlock()
|
||||
Init()
|
||||
mux.Lock()
|
||||
}
|
||||
|
||||
var err error
|
||||
|
@ -423,6 +443,38 @@ func retrieve(name string, ts ...time.Time) ([]byte, time.Time, error) {
|
|||
return ret, t, err
|
||||
}
|
||||
|
||||
type TidyFunc func(*bolt.Bucket) int
|
||||
|
||||
type TidyConfig struct {
|
||||
Interval time.Duration
|
||||
Func TidyFunc
|
||||
}
|
||||
|
||||
func ExpireAfter(exp time.Duration) TidyFunc {
|
||||
if exp > 0 {
|
||||
exp = -1 * exp
|
||||
}
|
||||
fmt.Println("ExpireAfter(",exp,")")
|
||||
return func(b *bolt.Bucket) int {
|
||||
stime := time.Now()
|
||||
etime := stime.Add(exp)
|
||||
i := 0
|
||||
c := b.Cursor()
|
||||
end,_ := c.Last() // always keep the most recent on
|
||||
for k,_ := c.First(); time.Since(stime) < 10 * time.Millisecond; k,_ = c.Next() {
|
||||
if tdecode(k).After(etime) {
|
||||
return i // entry not expired
|
||||
}
|
||||
if reflect.DeepEqual(k,end) {
|
||||
return i // always keep the most recent entry
|
||||
}
|
||||
b.Delete(k)
|
||||
i++
|
||||
}
|
||||
return i
|
||||
}
|
||||
}
|
||||
|
||||
func tidyThread() {
|
||||
fmt.Println("tidyThread() starting")
|
||||
lchan := make(chan string)
|
||||
|
@ -442,7 +494,7 @@ func tidyThread() {
|
|||
close(lchan)
|
||||
}
|
||||
}()
|
||||
tick := time.NewTicker(time.Second * 10)
|
||||
tick := time.NewTicker(conf.Tidy.Interval)
|
||||
for { select {
|
||||
case <-tchan:
|
||||
fmt.Println("closing loaded channel")
|
||||
|
@ -457,12 +509,9 @@ func tidyThread() {
|
|||
} }
|
||||
}
|
||||
|
||||
const expiration time.Duration = -24 * time.Hour
|
||||
|
||||
// discard entries if they are too old.
|
||||
func Tidy(name string) {
|
||||
stime := time.Now()
|
||||
etime := stime.Add(expiration)
|
||||
mux.Lock()
|
||||
i := 0
|
||||
db.Update(func(tx *bolt.Tx) error {
|
||||
|
@ -471,19 +520,7 @@ func Tidy(name string) {
|
|||
fmt.Println("Can't open bucket for ",name)
|
||||
return nil
|
||||
}
|
||||
c := b.Cursor()
|
||||
end,_ := c.Last() // always keep the most recent on
|
||||
for time.Since(stime) < 10 * time.Millisecond {
|
||||
k,_ := c.First()
|
||||
if tdecode(k).After(etime) {
|
||||
return nil // entry not expired
|
||||
}
|
||||
if reflect.DeepEqual(k,end) {
|
||||
return nil // always keep the most recent entry
|
||||
}
|
||||
b.Delete(k)
|
||||
i++
|
||||
}
|
||||
i = conf.Tidy.Func(b)
|
||||
return nil
|
||||
})
|
||||
mux.Unlock()
|
||||
|
|
27
test/tidy/main.go
Normal file
27
test/tidy/main.go
Normal file
|
@ -0,0 +1,27 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
"gitlab.wow.st/gmp/persist"
|
||||
)
|
||||
|
||||
func main() {
|
||||
tc := persist.TidyConfig{
|
||||
Interval: 2 * time.Second,
|
||||
Func:persist.ExpireAfter(-5 * time.Second),
|
||||
}
|
||||
persist.Init(persist.Config{Tidy: tc})
|
||||
|
||||
x := persistInt("x",0)
|
||||
persist.Commit()
|
||||
x.Set(2)
|
||||
persist.Commit()
|
||||
x.Set(3)
|
||||
persist.Commit()
|
||||
fmt.Println(x.History())
|
||||
time.Sleep(time.Second * 15)
|
||||
fmt.Println(x.History())
|
||||
persist.Shutdown()
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user