diff --git a/go/operation/lookup.go b/go/operation/lookup.go index e9d1586a3..2eea1ab34 100644 --- a/go/operation/lookup.go +++ b/go/operation/lookup.go @@ -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) diff --git a/go/operation/lookup_vid_cache.go b/go/operation/lookup_vid_cache.go new file mode 100644 index 000000000..72e7da924 --- /dev/null +++ b/go/operation/lookup_vid_cache.go @@ -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) + +} diff --git a/go/operation/lookup_vid_cache_test.go b/go/operation/lookup_vid_cache_test.go new file mode 100644 index 000000000..9c9e2affb --- /dev/null +++ b/go/operation/lookup_vid_cache_test.go @@ -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") + } +}