feat(all): setting a ByteView after marshaling the value into a byte buffer

This commit is contained in:
censhin 2021-04-30 11:09:01 -04:00
parent fa896fa6c1
commit a88b9ce0a6
4 changed files with 58 additions and 3 deletions

View File

@ -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 {

View File

@ -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 {

17
http.go
View File

@ -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 {

View File

@ -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) {