From a88b9ce0a6a26859efd9aa35b114bd221f2b60da Mon Sep 17 00:00:00 2001 From: censhin Date: Fri, 30 Apr 2021 11:09:01 -0400 Subject: [PATCH] feat(all): setting a ByteView after marshaling the value into a byte buffer --- groupcache.go | 18 +++++++++++++++--- groupcache_test.go | 8 ++++++++ http.go | 17 +++++++++++++++++ http_test.go | 18 ++++++++++++++++++ 4 files changed, 58 insertions(+), 3 deletions(-) diff --git a/groupcache.go b/groupcache.go index 9a4f5fd..162ccfa 100644 --- a/groupcache.go +++ b/groupcache.go @@ -26,6 +26,7 @@ package groupcache import ( "context" + "encoding/json" "errors" "strconv" "sync" @@ -116,6 +117,7 @@ func newGroup(name string, cacheBytes int64, getter Getter, peers PeerPicker) *G peers: peers, cacheBytes: cacheBytes, loadGroup: &singleflight.Group{}, + setGroup: &singleflight.Group{}, removeGroup: &singleflight.Group{}, } if fn := newGroupHook; fn != nil { @@ -510,9 +512,19 @@ func (g *Group) localSet(key string, value interface{}) { return } + buf, err := json.Marshal(value) + if err != nil { + return + } + + bv := ByteView{ + b: buf, + e: time.Time{}, + } + g.loadGroup.Lock(func() { - g.hotCache.set(key, value) - g.mainCache.set(key, value) + g.hotCache.set(key, bv) + g.mainCache.set(key, bv) }) } @@ -634,7 +646,7 @@ func (c *cache) get(key string) (value ByteView, ok bool) { return vi.(ByteView), true } -func (c *cache) set(key string, value interface{}) { +func (c *cache) set(key string, value ByteView) { c.mu.Lock() defer c.mu.Unlock() if c.lru == nil { diff --git a/groupcache_test.go b/groupcache_test.go index a99a60e..0ed0a23 100644 --- a/groupcache_test.go +++ b/groupcache_test.go @@ -263,6 +263,14 @@ func (p *fakePeer) Get(_ context.Context, in *pb.GetRequest, out *pb.GetResponse return nil } +func (p *fakePeer) Set(_ context.Context, in *pb.GetRequest) error { + p.hits++ + if p.fail { + return errors.New("simulated error from peer") + } + return nil +} + func (p *fakePeer) Remove(_ context.Context, in *pb.GetRequest) error { p.hits++ if p.fail { diff --git a/http.go b/http.go index 3048afc..9e9d4ee 100644 --- a/http.go +++ b/http.go @@ -285,6 +285,23 @@ func (h *httpGetter) Get(ctx context.Context, in *pb.GetRequest, out *pb.GetResp return nil } +func (h *httpGetter) Set(ctx context.Context, in *pb.GetRequest) error { + var res http.Response + if err := h.makeRequest(ctx, http.MethodPut, in, &res); err != nil { + return err + } + defer res.Body.Close() + + if res.StatusCode != http.StatusOK { + body, err := ioutil.ReadAll(res.Body) + if err != nil { + return fmt.Errorf("while reading body response: %v", res.Status) + } + return fmt.Errorf("server returned status %d: %s", res.StatusCode, body) + } + return nil +} + func (h *httpGetter) Remove(ctx context.Context, in *pb.GetRequest) error { var res http.Response if err := h.makeRequest(ctx, http.MethodDelete, in, &res); err != nil { diff --git a/http_test.go b/http_test.go index d3b40d4..785b38f 100644 --- a/http_test.go +++ b/http_test.go @@ -151,6 +151,24 @@ func TestHTTPPool(t *testing.T) { if serverHits != 2 { t.Error("expected serverHits to be '2'") } + + key = "setTestKey" + setValue := "test set" + var getValue string + // Add the key to the cache + if err := g.Set(ctx, key, setValue); err != nil { + t.Fatal(err) + } + + // Get the key + if err := g.Get(ctx, key, StringSink(&getValue)); err != nil { + t.Fatal(err) + } + + // TODO: why is this like this? + if fmt.Sprintf("\"%s\"", setValue) != getValue { + t.Fatal(errors.New(fmt.Sprintf("incorrect value retrieved after set: %s", getValue))) + } } func testKeys(n int) (keys []string) {