OLD | NEW |
| (Empty) |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 package prod | |
6 | |
7 import ( | |
8 "time" | |
9 | |
10 "github.com/luci/gae" | |
11 "golang.org/x/net/context" | |
12 "google.golang.org/appengine/memcache" | |
13 ) | |
14 | |
15 // useMC adds a gae.Memcache implementation to context, accessible | |
16 // by gae.GetMC(c) | |
17 func useMC(c context.Context) context.Context { | |
18 return gae.SetMCFactory(c, func(ci context.Context) gae.Memcache { | |
19 return mcImpl{ci} | |
20 }) | |
21 } | |
22 | |
23 type mcImpl struct{ context.Context } | |
24 | |
25 type mcItem struct { | |
26 i *memcache.Item | |
27 } | |
28 | |
29 var _ gae.MCItem = mcItem{} | |
30 | |
31 func (i mcItem) Key() string { return i.i.Key } | |
32 func (i mcItem) Value() []byte { return i.i.Value } | |
33 func (i mcItem) Object() interface{} { return i.i.Object } | |
34 func (i mcItem) Flags() uint32 { return i.i.Flags } | |
35 func (i mcItem) Expiration() time.Duration { return i.i.Expiration } | |
36 | |
37 func (i mcItem) SetKey(k string) gae.MCItem { | |
38 i.i.Key = k | |
39 return i | |
40 } | |
41 func (i mcItem) SetValue(v []byte) gae.MCItem { | |
42 i.i.Value = v | |
43 return i | |
44 } | |
45 func (i mcItem) SetObject(o interface{}) gae.MCItem { | |
46 i.i.Object = o | |
47 return i | |
48 } | |
49 func (i mcItem) SetFlags(f uint32) gae.MCItem { | |
50 i.i.Flags = f | |
51 return i | |
52 } | |
53 func (i mcItem) SetExpiration(d time.Duration) gae.MCItem { | |
54 i.i.Expiration = d | |
55 return i | |
56 } | |
57 | |
58 // mcR2FErr (MC real-to-fake w/ error) converts a *memcache.Item to a gae.MCItem
, | |
59 // and passes along an error. | |
60 func mcR2FErr(i *memcache.Item, err error) (gae.MCItem, error) { | |
61 if err != nil { | |
62 return nil, err | |
63 } | |
64 return mcItem{i}, nil | |
65 } | |
66 | |
67 // mcF2R (MC fake-to-real) converts a gae.MCItem. i must originate from inside | |
68 // this package for this function to work (see the panic message for why). | |
69 func mcF2R(i gae.MCItem) *memcache.Item { | |
70 if mci, ok := i.(mcItem); ok { | |
71 return mci.i | |
72 } | |
73 panic( | |
74 "you may not use other gae.MCItem implementations with this " + | |
75 "implementation of gae.Memcache, since it will cause all
CompareAndSwap " + | |
76 "operations to fail. Please use the NewItem api instead.
") | |
77 } | |
78 | |
79 // mcMF2R (MC multi-fake-to-real) converts a slice of gae.MCItem to a slice of | |
80 // *memcache.Item. | |
81 func mcMF2R(items []gae.MCItem) []*memcache.Item { | |
82 realItems := make([]*memcache.Item, len(items)) | |
83 for i, itm := range items { | |
84 realItems[i] = mcF2R(itm) | |
85 } | |
86 return realItems | |
87 } | |
88 | |
89 func (m mcImpl) NewItem(key string) gae.MCItem { | |
90 return mcItem{&memcache.Item{Key: key}} | |
91 } | |
92 | |
93 //////// MCSingleReadWriter | |
94 func (m mcImpl) Add(item gae.MCItem) error { | |
95 return memcache.Add(m.Context, mcF2R(item)) | |
96 } | |
97 func (m mcImpl) Set(item gae.MCItem) error { | |
98 return memcache.Set(m.Context, mcF2R(item)) | |
99 } | |
100 func (m mcImpl) Delete(key string) error { | |
101 return memcache.Delete(m.Context, key) | |
102 } | |
103 func (m mcImpl) Get(key string) (gae.MCItem, error) { | |
104 return mcR2FErr(memcache.Get(m.Context, key)) | |
105 } | |
106 func (m mcImpl) CompareAndSwap(item gae.MCItem) error { | |
107 return memcache.CompareAndSwap(m.Context, mcF2R(item)) | |
108 } | |
109 | |
110 //////// MCMultiReadWriter | |
111 func (m mcImpl) DeleteMulti(keys []string) error { | |
112 return gae.FixError(memcache.DeleteMulti(m.Context, keys)) | |
113 } | |
114 func (m mcImpl) AddMulti(items []gae.MCItem) error { | |
115 return gae.FixError(memcache.AddMulti(m.Context, mcMF2R(items))) | |
116 } | |
117 func (m mcImpl) SetMulti(items []gae.MCItem) error { | |
118 return gae.FixError(memcache.SetMulti(m.Context, mcMF2R(items))) | |
119 } | |
120 func (m mcImpl) GetMulti(keys []string) (map[string]gae.MCItem, error) { | |
121 realItems, err := memcache.GetMulti(m.Context, keys) | |
122 if err != nil { | |
123 return nil, gae.FixError(err) | |
124 } | |
125 items := make(map[string]gae.MCItem, len(realItems)) | |
126 for k, itm := range realItems { | |
127 items[k] = mcItem{itm} | |
128 } | |
129 return items, err | |
130 } | |
131 func (m mcImpl) CompareAndSwapMulti(items []gae.MCItem) error { | |
132 return gae.FixError(memcache.CompareAndSwapMulti(m.Context, mcMF2R(items
))) | |
133 } | |
134 | |
135 //////// MCIncrementer | |
136 func (m mcImpl) Increment(key string, delta int64, initialValue uint64) (uint64,
error) { | |
137 return memcache.Increment(m.Context, key, delta, initialValue) | |
138 } | |
139 func (m mcImpl) IncrementExisting(key string, delta int64) (uint64, error) { | |
140 return memcache.IncrementExisting(m.Context, key, delta) | |
141 } | |
142 | |
143 //////// MCFlusher | |
144 func (m mcImpl) Flush() error { | |
145 return memcache.Flush(m.Context) | |
146 } | |
147 | |
148 //////// MCStatter | |
149 func (m mcImpl) Stats() (*gae.MCStatistics, error) { | |
150 stats, err := memcache.Stats(m.Context) | |
151 if err != nil { | |
152 return nil, err | |
153 } | |
154 return (*gae.MCStatistics)(stats), nil | |
155 } | |
OLD | NEW |