mirror of
https://github.com/mailgun/groupcache.git
synced 2024-07-01 02:19:12 +00:00
feat(all): setting a ByteView after marshaling the value into a byte buffer
This commit is contained in:
parent
fa896fa6c1
commit
a88b9ce0a6
|
@ -26,6 +26,7 @@ package groupcache
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"strconv"
|
"strconv"
|
||||||
"sync"
|
"sync"
|
||||||
|
@ -116,6 +117,7 @@ func newGroup(name string, cacheBytes int64, getter Getter, peers PeerPicker) *G
|
||||||
peers: peers,
|
peers: peers,
|
||||||
cacheBytes: cacheBytes,
|
cacheBytes: cacheBytes,
|
||||||
loadGroup: &singleflight.Group{},
|
loadGroup: &singleflight.Group{},
|
||||||
|
setGroup: &singleflight.Group{},
|
||||||
removeGroup: &singleflight.Group{},
|
removeGroup: &singleflight.Group{},
|
||||||
}
|
}
|
||||||
if fn := newGroupHook; fn != nil {
|
if fn := newGroupHook; fn != nil {
|
||||||
|
@ -510,9 +512,19 @@ func (g *Group) localSet(key string, value interface{}) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
buf, err := json.Marshal(value)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
bv := ByteView{
|
||||||
|
b: buf,
|
||||||
|
e: time.Time{},
|
||||||
|
}
|
||||||
|
|
||||||
g.loadGroup.Lock(func() {
|
g.loadGroup.Lock(func() {
|
||||||
g.hotCache.set(key, value)
|
g.hotCache.set(key, bv)
|
||||||
g.mainCache.set(key, value)
|
g.mainCache.set(key, bv)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -634,7 +646,7 @@ func (c *cache) get(key string) (value ByteView, ok bool) {
|
||||||
return vi.(ByteView), true
|
return vi.(ByteView), true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *cache) set(key string, value interface{}) {
|
func (c *cache) set(key string, value ByteView) {
|
||||||
c.mu.Lock()
|
c.mu.Lock()
|
||||||
defer c.mu.Unlock()
|
defer c.mu.Unlock()
|
||||||
if c.lru == nil {
|
if c.lru == nil {
|
||||||
|
|
|
@ -263,6 +263,14 @@ func (p *fakePeer) Get(_ context.Context, in *pb.GetRequest, out *pb.GetResponse
|
||||||
return nil
|
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 {
|
func (p *fakePeer) Remove(_ context.Context, in *pb.GetRequest) error {
|
||||||
p.hits++
|
p.hits++
|
||||||
if p.fail {
|
if p.fail {
|
||||||
|
|
17
http.go
17
http.go
|
@ -285,6 +285,23 @@ func (h *httpGetter) Get(ctx context.Context, in *pb.GetRequest, out *pb.GetResp
|
||||||
return nil
|
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 {
|
func (h *httpGetter) Remove(ctx context.Context, in *pb.GetRequest) error {
|
||||||
var res http.Response
|
var res http.Response
|
||||||
if err := h.makeRequest(ctx, http.MethodDelete, in, &res); err != nil {
|
if err := h.makeRequest(ctx, http.MethodDelete, in, &res); err != nil {
|
||||||
|
|
18
http_test.go
18
http_test.go
|
@ -151,6 +151,24 @@ func TestHTTPPool(t *testing.T) {
|
||||||
if serverHits != 2 {
|
if serverHits != 2 {
|
||||||
t.Error("expected serverHits to be '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) {
|
func testKeys(n int) (keys []string) {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user