44 "errors"
55 "net"
66 "strconv"
7+ "time"
78
89 "github.com/weaveworks/mesh"
910 "golang.org/x/sync/singleflight"
@@ -22,10 +23,11 @@ var (
2223
2324// Bcache represents bcache struct
2425type Bcache struct {
25- peer * peer
26- router * mesh.Router
27- logger Logger
28- flight singleflight.Group
26+ peer * peer
27+ router * mesh.Router
28+ logger Logger
29+ flight singleflight.Group
30+ deletionDelay time.Duration
2931}
3032
3133// New creates new bcache from the given config
@@ -89,40 +91,45 @@ func New(cfg Config) (*Bcache, error) {
8991 router .ConnectionMaker .InitiateConnections (cfg .Peers , true )
9092
9193 return & Bcache {
92- peer : peer ,
93- router : router ,
94- logger : logger ,
94+ peer : peer ,
95+ router : router ,
96+ logger : logger ,
97+ deletionDelay : time .Duration (cfg .DeletionDelay ) * time .Second ,
9598 }, nil
9699}
97100
98- // Set sets value for the given key.
99- //
100- // expiredTimestamp could be used in these way:
101- //
102- // - unix timestamp when this key will be expired
103- // - as a way to decide which value is the newer when doing data synchronization among nodes
104- func (b * Bcache ) Set (key , val string , expiredTimestamp int64 ) {
105- b .peer .Set (key , val , expiredTimestamp )
101+ // Set sets value for the given key with the given ttl in second.
102+ // if ttl <= 0, the key will expired instantly
103+ func (b * Bcache ) Set (key , val string , ttl int ) {
104+ if ttl <= 0 {
105+ b .Delete (key )
106+ return
107+ }
108+ b .set (key , val , ttl )
109+ }
110+
111+ func (b * Bcache ) set (key , val string , ttl int ) int64 {
112+ expired := time .Now ().Add (time .Duration (ttl ) * time .Second ).UnixNano ()
113+ b .peer .Set (key , val , expired )
114+ return expired
106115}
107116
108117// Get gets value for the given key.
109118//
110- // It returns the value, expiration timestamp, and true if the key exists
111- func (b * Bcache ) Get (key string ) (string , int64 , bool ) {
119+ // It returns the value and true if the key exists
120+ func (b * Bcache ) Get (key string ) (string , bool ) {
112121 return b .peer .Get (key )
113122}
114123
115124// Delete the given key.
116125//
117- // The given timestamp is used to decide which operation is the lastes when doing syncronization.
118- //
119- // For example: `Delete` with timestamp 3 and `Set` with timestamp 4 -> `Set` is the latest, so the `Delete` is ignored
120- func (b * Bcache ) Delete (key string , expiredTimestamp int64 ) {
121- b .peer .Delete (key , expiredTimestamp )
126+ func (b * Bcache ) Delete (key string ) {
127+ deleteTs := time .Now ().Add (b .deletionDelay ).UnixNano ()
128+ b .peer .Delete (key , deleteTs )
122129}
123130
124131// Filler defines func to be called when the given key is not exists
125- type Filler func (key string ) (val string , expired int64 , err error )
132+ type Filler func (key string ) (val string , err error )
126133
127134// GetWithFiller gets value for the given key and fill the cache
128135// if the given key is not exists.
@@ -134,27 +141,26 @@ type Filler func(key string) (val string, expired int64, err error)
134141//
135142//
136143// It useful to avoid cache stampede to the underlying database
137- func (b * Bcache ) GetWithFiller (key string , filler Filler ) (string , int64 , error ) {
144+ func (b * Bcache ) GetWithFiller (key string , filler Filler , ttl int ) (string , error ) {
138145 if filler == nil {
139- return "" , 0 , ErrNilFiller
146+ return "" , ErrNilFiller
140147 }
141148
142149 // get value from cache
143- val , exp , ok := b .Get (key )
150+ val , ok := b .Get (key )
144151 if ok {
145- return val , exp , nil
152+ return val , nil
146153 }
147154
148155 // construct singleflight filler
149156 flightFn := func () (interface {}, error ) {
150- val , expired , err := filler (key )
157+ val , err := filler (key )
151158 if err != nil {
152159 b .logger .Errorf ("filler failed: %v" , err )
153160 return nil , err
154161 }
155162
156- // set the key if filler OK
157- b .peer .Set (key , val , expired )
163+ expired := b .set (key , val , ttl )
158164
159165 return value {
160166 value : val ,
@@ -167,12 +173,12 @@ func (b *Bcache) GetWithFiller(key string, filler Filler) (string, int64, error)
167173 return flightFn ()
168174 })
169175 if err != nil {
170- return "" , 0 , err
176+ return "" , err
171177 }
172178
173179 // return the value
174180 value := valueIf .(value )
175- return value .value , value . expired , nil
181+ return value .value , nil
176182}
177183
178184// Close closes the cache, free all the resource
0 commit comments