Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(336)

Unified Diff: service/memcache/interface.go

Issue 2302743002: Interface update, per-method Contexts. (Closed)
Patch Set: Lightning talk licenses. Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « service/memcache/context.go ('k') | service/memcache/memcache.go » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: service/memcache/interface.go
diff --git a/service/memcache/interface.go b/service/memcache/interface.go
index 6d4d33b2d880660f5b499adce34836c6d57bb7e1..5167667587da615f095f0827977a3dd127969776 100644
--- a/service/memcache/interface.go
+++ b/service/memcache/interface.go
@@ -4,72 +4,177 @@
package memcache
-// Interface is the full interface to the memcache service.
+import (
+ "github.com/luci/luci-go/common/errors"
+ "golang.org/x/net/context"
+)
+
+func filterItems(lme errors.LazyMultiError, items []Item, nilErr error) ([]Item, []int) {
+ idxMap := make([]int, 0, len(items))
+ retItems := make([]Item, 0, len(items))
+ for i, itm := range items {
+ if itm != nil {
+ idxMap = append(idxMap, i)
+ retItems = append(retItems, itm)
+ } else {
+ lme.Assign(i, nilErr)
+ }
+ }
+ return retItems, idxMap
+}
+
+func multiCall(items []Item, nilErr error, inner func(items []Item, cb RawCB) error) error {
+ lme := errors.NewLazyMultiError(len(items))
+ realItems, idxMap := filterItems(lme, items, nilErr)
+ j := 0
+ err := inner(realItems, func(err error) {
+ lme.Assign(idxMap[j], err)
+ j++
+ })
+ if err == nil {
+ err = lme.Get()
+ if len(items) == 1 {
+ err = errors.SingleError(err)
+ }
+ }
+ return err
+}
+
+// NewItem creates a new, mutable, memcache item.
+func NewItem(c context.Context, key string) Item {
+ return Raw(c).NewItem(key)
+}
+
+// Add writes items to memcache iff they don't already exist.
+//
+// If only one item is provided its error will be returned directly. If more
+// than one item is provided, an errors.MultiError will be returned in the
+// event of an error, with a given error index corresponding to the error
+// encountered when processing the item at that index.
+func Add(c context.Context, items ...Item) error {
+ return multiCall(items, ErrNotStored, Raw(c).AddMulti)
+}
+
+// Set writes items into memcache unconditionally.
+//
+// If only one item is provided its error will be returned directly. If more
+// than one item is provided, an errors.MultiError will be returned in the
+// event of an error, with a given error index corresponding to the error
+// encountered when processing the item at that index.
+func Set(c context.Context, items ...Item) error {
+ return multiCall(items, ErrNotStored, Raw(c).SetMulti)
+}
+
+func getMultiImpl(raw RawInterface, items []Item) error {
+ lme := errors.NewLazyMultiError(len(items))
+ realItems, idxMap := filterItems(lme, items, ErrCacheMiss)
+ if len(realItems) == 0 {
+ return lme.Get()
+ }
+
+ keys := make([]string, len(realItems))
+ for i, itm := range realItems {
+ keys[i] = itm.Key()
+ }
+
+ j := 0
+ err := raw.GetMulti(keys, func(item Item, err error) {
+ i := idxMap[j]
+ if !lme.Assign(i, err) {
+ items[i].SetAll(item)
+ }
+ j++
+ })
+ if err == nil {
+ err = lme.Get()
+ if len(items) == 1 {
+ err = errors.SingleError(err)
+ }
+ }
+ return err
+}
+
+// Get retrieves items from memcache.
+func Get(c context.Context, items ...Item) error {
+ return getMultiImpl(Raw(c), items)
+}
+
+// GetKey is a convenience method for generating and retrieving an Item instance
+// for the specified from memcache key.
+//
+// On a cache miss ErrCacheMiss will be returned. Item will always be
+// returned, even on a miss, but it's value may be empty if it was a miss.
+func GetKey(c context.Context, key string) (Item, error) {
+ raw := Raw(c)
+ ret := raw.NewItem(key)
+ err := getMultiImpl(raw, []Item{ret})
+ return ret, err
+}
+
+// Delete deletes items from memcache.
+//
+// If only one item is provided its error will be returned directly. If more
+// than one item is provided, an errors.MultiError will be returned in the
+// event of an error, with a given error index corresponding to the error
+// encountered when processing the item at that index.
+func Delete(c context.Context, keys ...string) error {
+ lme := errors.NewLazyMultiError(len(keys))
+ i := 0
+ err := Raw(c).DeleteMulti(keys, func(err error) {
+ lme.Assign(i, err)
+ i++
+ })
+ if err == nil {
+ err = lme.Get()
+ if len(keys) == 1 {
+ err = errors.SingleError(err)
+ }
+ }
+ return err
+}
+
+// CompareAndSwap writes the given item that was previously returned by Get, if
+// the value was neither modified or evicted between the Get and the
+// CompareAndSwap calls.
+//
+// Example:
+// itm := memcache.NewItem(context, "aKey")
+// memcache.Get(context, itm) // check error
+// itm.SetValue(append(itm.Value(), []byte("more bytes")))
+// memcache.CompareAndSwap(context, itm) // check error
+//
+// If only one item is provided its error will be returned directly. If more
+// than one item is provided, an errors.MultiError will be returned in the
+// event of an error, with a given error index corresponding to the error
+// encountered when processing the item at that index.
+func CompareAndSwap(c context.Context, items ...Item) error {
+ return multiCall(items, ErrNotStored, Raw(c).CompareAndSwapMulti)
+}
+
+// Increment adds delta to the uint64 contained at key. If the memcache key
+// is missing, it's populated with initialValue before applying delta (i.e.
+// the final value would be initialValue+delta).
+//
+// Underflow caps at 0, overflow wraps back to 0.
//
-// The *Multi methods may return a "github.com/luci/luci-go/common/errors".MultiError
-// if the rpc to the server was successful, but, e.g. some of the items were
-// missing. They may also return a regular error, if, for example, the rpc
-// failed outright.
-type Interface interface {
- // NewItem creates a new, mutable, memcache item.
- NewItem(key string) Item
-
- // Add puts a single item into memcache, but only if it didn't exist in
- // memcache before.
- Add(item Item) error
-
- // Set the item in memcache, whether or not it exists.
- Set(item Item) error
-
- // Get retrieves an item from memcache.
- //
- // On a cache miss ErrCacheMiss will be returned. Item will always be
- // returned, even on a miss, but it's value may be empty if it was a miss.
- Get(key string) (Item, error)
-
- // Delete removes an item from memcache.
- Delete(key string) error
-
- // CompareAndSwap accepts an item which is the result of Get() or GetMulti().
- // The Get functions add a secret field to item ('CasID'), which is used as
- // the "compare" value for the "CompareAndSwap". The actual "Value" field of
- // the object set by the Get functions is the "swap" value.
- //
- // Example:
- // mc := memcache.Get(context)
- // itm := mc.NewItem("aKey")
- // mc.Get(itm) // check error
- // itm.SetValue(append(itm.Value(), []byte("more bytes")))
- // mc.CompareAndSwap(itm) // check error
- CompareAndSwap(item Item) error
-
- // Batch operations; GetMulti takes a []Item instead of []string to improve
- // ergonomics when streamlining these operations.
- AddMulti(items []Item) error
- SetMulti(items []Item) error
- GetMulti(items []Item) error
- DeleteMulti(keys []string) error
- CompareAndSwapMulti(items []Item) error
-
- // Increment adds delta to the uint64 contained at key. If the memcache key
- // is missing, it's populated with initialValue before applying delta (i.e.
- // the final value would be initialValue+delta).
- //
- // Underflow caps at 0, overflow wraps back to 0.
- //
- // If key contains a value which is not exactly 8 bytes, it's assumed to
- // contain non-number data and this method will return an error.
- Increment(key string, delta int64, initialValue uint64) (newValue uint64, err error)
-
- // IncrementExisting is like Increment, except that the valu must exist
- // already.
- IncrementExisting(key string, delta int64) (newValue uint64, err error)
-
- // Flush dumps the entire memcache state.
- Flush() error
-
- // Stats gets some best-effort statistics about the current state of memcache.
- Stats() (*Statistics, error)
-
- Raw() RawInterface
+// If key contains a value which is not exactly 8 bytes, it's assumed to
+// contain non-number data and this method will return an error.
+func Increment(c context.Context, key string, delta int64, initialValue uint64) (uint64, error) {
+ return Raw(c).Increment(key, delta, &initialValue)
+}
+
+// IncrementExisting is like Increment, except that the valu must exist
+// already.
+func IncrementExisting(c context.Context, key string, delta int64) (uint64, error) {
+ return Raw(c).Increment(key, delta, nil)
+}
+
+// Flush dumps the entire memcache state.
+func Flush(c context.Context) error {
+ return Raw(c).Flush()
+}
+
+// Stats gets some best-effort statistics about the current state of memcache.
+func Stats(c context.Context) (*Statistics, error) {
+ return Raw(c).Stats()
}
« no previous file with comments | « service/memcache/context.go ('k') | service/memcache/memcache.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698