Chromium Code Reviews| Index: go/src/infra/gae/libs/gae/prod/memcache.go |
| diff --git a/go/src/infra/gae/libs/gae/prod/memcache.go b/go/src/infra/gae/libs/gae/prod/memcache.go |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..b4e9027e43ef22d23263f496a24bf8138bdb7b04 |
| --- /dev/null |
| +++ b/go/src/infra/gae/libs/gae/prod/memcache.go |
| @@ -0,0 +1,180 @@ |
| +// Copyright 2015 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +package prod |
| + |
| +import ( |
| + "golang.org/x/net/context" |
|
Vadim Sh.
2015/07/14 00:12:37
move below
iannucci
2015/07/14 01:07:46
oh really? I've been including this one as a 'stan
|
| + "time" |
| + |
| + "infra/gae/libs/gae" |
| + |
| + "google.golang.org/appengine/memcache" |
| +) |
| + |
| +// useMC adds a gae.Memcache implementation to context, accessible |
| +// by gae.GetMC(c) |
| +func useMC(c context.Context) context.Context { |
| + return gae.SetMCFactory(c, func(ci context.Context) gae.Memcache { |
| + return mcImpl{ci} |
| + }) |
| +} |
| + |
| +type mcImpl struct{ context.Context } |
| + |
| +type mcItem struct { |
| + i *memcache.Item |
| +} |
| + |
| +var _ gae.MCItem = mcItem{} |
| + |
| +func (i mcItem) Key() string { return i.i.Key } |
| +func (i mcItem) Value() []byte { return i.i.Value } |
| +func (i mcItem) Object() interface{} { return i.i.Object } |
| +func (i mcItem) Flags() uint32 { return i.i.Flags } |
| +func (i mcItem) Expiration() time.Duration { return i.i.Expiration } |
| + |
| +func (i mcItem) SetKey(k string) gae.MCItem { |
| + i.i.Key = k |
| + return i |
| +} |
| +func (i mcItem) SetValue(v []byte) gae.MCItem { |
| + i.i.Value = v |
| + return i |
| +} |
| +func (i mcItem) SetObject(o interface{}) gae.MCItem { |
| + i.i.Object = o |
| + return i |
| +} |
| +func (i mcItem) SetFlags(f uint32) gae.MCItem { |
| + i.i.Flags = f |
| + return i |
| +} |
| +func (i mcItem) SetExpiration(d time.Duration) gae.MCItem { |
| + i.i.Expiration = d |
| + return i |
| +} |
| + |
| +func mc2fe(i *memcache.Item, err error) (gae.MCItem, error) { |
| + if err != nil { |
| + return nil, err |
| + } |
| + return mcItem{i}, nil |
| +} |
| + |
| +func f2mc(i gae.MCItem) *memcache.Item { |
| + return i.(mcItem).i |
| +} |
| + |
| +func mf2mc(items []gae.MCItem) []*memcache.Item { |
| + realItems := make([]*memcache.Item, len(items)) |
| + for i, itm := range items { |
| + realItems[i] = f2mc(itm) |
| + } |
| + return realItems |
| +} |
| + |
| +func (m mcImpl) NewItem(key string) gae.MCItem { |
| + return mcItem{&memcache.Item{Key: key}} |
| +} |
| + |
| +//////// MCSingleReadWriter |
| +func (m mcImpl) Add(item gae.MCItem) error { |
| + return memcache.Add(m.Context, f2mc(item)) |
| +} |
| +func (m mcImpl) Set(item gae.MCItem) error { |
| + return memcache.Set(m.Context, f2mc(item)) |
| +} |
| +func (m mcImpl) Delete(key string) error { |
| + return memcache.Delete(m.Context, key) |
| +} |
| +func (m mcImpl) Get(key string) (gae.MCItem, error) { |
| + return mc2fe(memcache.Get(m.Context, key)) |
| +} |
| +func (m mcImpl) CompareAndSwap(item gae.MCItem) error { |
| + return memcache.CompareAndSwap(m.Context, f2mc(item)) |
| +} |
| + |
| +//////// MCMultiReadWriter |
| +func (m mcImpl) DeleteMulti(keys []string) error { |
| + return gae.FixError(memcache.DeleteMulti(m.Context, keys)) |
| +} |
| +func (m mcImpl) AddMulti(items []gae.MCItem) error { |
| + return gae.FixError(memcache.AddMulti(m.Context, mf2mc(items))) |
| +} |
| +func (m mcImpl) SetMulti(items []gae.MCItem) error { |
| + return gae.FixError(memcache.SetMulti(m.Context, mf2mc(items))) |
| +} |
| +func (m mcImpl) GetMulti(keys []string) (map[string]gae.MCItem, error) { |
| + realItems, err := memcache.GetMulti(m.Context, keys) |
| + if err != nil { |
| + return nil, gae.FixError(err) |
| + } |
| + items := make(map[string]gae.MCItem, len(realItems)) |
| + for k, itm := range realItems { |
| + items[k] = mcItem{itm} |
| + } |
| + return items, err |
| +} |
| +func (m mcImpl) CompareAndSwapMulti(items []gae.MCItem) error { |
| + return gae.FixError(memcache.CompareAndSwapMulti(m.Context, mf2mc(items))) |
| +} |
| + |
| +//////// MCIncrementer |
| +func (m mcImpl) Increment(key string, delta int64, initialValue uint64) (uint64, error) { |
| + return memcache.Increment(m.Context, key, delta, initialValue) |
| +} |
| +func (m mcImpl) IncrementExisting(key string, delta int64) (uint64, error) { |
| + return memcache.IncrementExisting(m.Context, key, delta) |
| +} |
| + |
| +//////// MCFlusher |
| +func (m mcImpl) Flush() error { |
| + return memcache.Flush(m.Context) |
| +} |
| + |
| +//////// MCStatter |
| +func (m mcImpl) Stats() (*gae.MCStatistics, error) { |
| + stats, err := memcache.Stats(m.Context) |
| + if err != nil { |
| + return nil, err |
| + } |
| + return (*gae.MCStatistics)(stats), nil |
| +} |
| + |
| +//////// MCCodecInflater |
| +type mcCodecCombiner struct { |
| + context.Context |
| + codec memcache.Codec |
| +} |
| + |
| +//////// MCCodecInflater.logger |
| +func (cc mcCodecCombiner) Set(item gae.MCItem) error { |
| + return cc.codec.Set(cc.Context, f2mc(item)) |
| +} |
| +func (cc mcCodecCombiner) Add(item gae.MCItem) error { |
| + return cc.codec.Add(cc.Context, f2mc(item)) |
| +} |
| +func (cc mcCodecCombiner) Get(key string, v interface{}) (gae.MCItem, error) { |
| + return mc2fe(cc.codec.Get(cc.Context, key, v)) |
| +} |
| +func (cc mcCodecCombiner) SetMulti(items []gae.MCItem) error { |
| + return gae.FixError(cc.codec.SetMulti(cc.Context, mf2mc(items))) |
| +} |
| +func (cc mcCodecCombiner) AddMulti(items []gae.MCItem) error { |
| + return gae.FixError(cc.codec.AddMulti(cc.Context, mf2mc(items))) |
| +} |
| +func (cc mcCodecCombiner) CompareAndSwap(item gae.MCItem) error { |
| + return cc.codec.CompareAndSwap(cc.Context, f2mc(item)) |
| +} |
| +func (cc mcCodecCombiner) CompareAndSwapMulti(items []gae.MCItem) error { |
| + return gae.FixError(cc.codec.CompareAndSwapMulti(cc.Context, mf2mc(items))) |
| +} |
| + |
| +func (m mcImpl) InflateCodec(codec gae.MCCodecDef) gae.MCCodec { |
| + return mcCodecCombiner{m.Context, memcache.Codec{ |
| + Marshal: codec.Marshal, |
| + Unmarshal: codec.Unmarshal, |
| + }} |
| +} |