Add volume id lookup caching

This commit is contained in:
Chris Lu 2014-05-25 14:01:54 -07:00
parent 38260fcfb1
commit b5f99b26eb
3 changed files with 84 additions and 1 deletions

View file

@ -8,6 +8,7 @@ import (
"math/rand"
"net/url"
"strings"
"time"
)
type Location struct {
@ -20,7 +21,22 @@ type LookupResult struct {
Error string `json:"error,omitempty"`
}
func Lookup(server string, vid string) (*LookupResult, error) {
var (
vc VidCache
)
func Lookup(server string, vid string) (ret *LookupResult, err error) {
locations, cache_err := vc.Get(vid)
if cache_err != nil {
ret, err = do_lookup(server, vid)
vc.Set(vid, ret.Locations, 1*time.Minute)
} else {
ret = &LookupResult{VolumeId: vid, Locations: locations}
}
return
}
func do_lookup(server string, vid string) (*LookupResult, error) {
values := make(url.Values)
values.Add("volumeId", vid)
jsonBlob, err := util.Post("http://"+server+"/dir/lookup", values)

View file

@ -0,0 +1,41 @@
package operation
import (
"errors"
"strconv"
"time"
)
type VidInfo struct {
Locations []Location
NextRefreshTime time.Time
}
type VidCache struct {
cache []VidInfo
}
func (vc *VidCache) Get(vid string) ([]Location, error) {
id, _ := strconv.Atoi(vid)
if 0 < id && id <= len(vc.cache) {
if vc.cache[id-1].Locations == nil {
return nil, errors.New("Not Set")
}
if vc.cache[id-1].NextRefreshTime.Before(time.Now()) {
return nil, errors.New("Expired")
}
return vc.cache[id-1].Locations, nil
}
return nil, errors.New("Not Found")
}
func (vc *VidCache) Set(vid string, locations []Location, duration time.Duration) {
id, _ := strconv.Atoi(vid)
if id >= len(vc.cache) {
for i := id - len(vc.cache); i > 0; i-- {
vc.cache = append(vc.cache, VidInfo{})
}
}
vc.cache[id-1].Locations = locations
vc.cache[id-1].NextRefreshTime = time.Now().Add(duration)
}

View file

@ -0,0 +1,26 @@
package operation
import (
"fmt"
"testing"
"time"
)
func TestCaching(t *testing.T) {
var (
vc VidCache
)
var locations []Location
locations = append(locations, Location{Url: "a.com:8080"})
vc.Set("123", locations, time.Second)
ret, _ := vc.Get("123")
if ret == nil {
t.Fatal("Not found vid 123")
}
fmt.Printf("vid 123 locations = %v\n", ret)
time.Sleep(2 * time.Second)
ret, _ = vc.Get("123")
if ret != nil {
t.Fatal("Not found vid 123")
}
}