aboutsummaryrefslogtreecommitdiff
path: root/go/operation
diff options
context:
space:
mode:
Diffstat (limited to 'go/operation')
-rw-r--r--go/operation/lookup.go18
-rw-r--r--go/operation/lookup_vid_cache.go41
-rw-r--r--go/operation/lookup_vid_cache_test.go26
3 files changed, 84 insertions, 1 deletions
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")
+ }
+}