OLD | NEW |
1 // Copyright 2015 The LUCI Authors. All rights reserved. | 1 // Copyright 2015 The LUCI Authors. All rights reserved. |
2 // Use of this source code is governed under the Apache License, Version 2.0 | 2 // Use of this source code is governed under the Apache License, Version 2.0 |
3 // that can be found in the LICENSE file. | 3 // that can be found in the LICENSE file. |
4 | 4 |
5 package dscache | 5 package dscache |
6 | 6 |
7 import ( | 7 import ( |
8 "time" | 8 "time" |
9 | 9 |
10 ds "github.com/luci/gae/service/datastore" | 10 ds "github.com/luci/gae/service/datastore" |
11 » "github.com/luci/gae/service/memcache" | 11 » mc "github.com/luci/gae/service/memcache" |
| 12 |
12 "github.com/luci/luci-go/common/errors" | 13 "github.com/luci/luci-go/common/errors" |
13 log "github.com/luci/luci-go/common/logging" | 14 log "github.com/luci/luci-go/common/logging" |
| 15 |
14 "golang.org/x/net/context" | 16 "golang.org/x/net/context" |
15 ) | 17 ) |
16 | 18 |
17 type dsCache struct { | 19 type dsCache struct { |
18 ds.RawInterface | 20 ds.RawInterface |
19 | 21 |
20 *supportContext | 22 *supportContext |
21 } | 23 } |
22 | 24 |
23 var _ ds.RawInterface = (*dsCache)(nil) | 25 var _ ds.RawInterface = (*dsCache)(nil) |
24 | 26 |
25 func (d *dsCache) DeleteMulti(keys []*ds.Key, cb ds.DeleteMultiCB) error { | 27 func (d *dsCache) DeleteMulti(keys []*ds.Key, cb ds.DeleteMultiCB) error { |
26 return d.mutation(keys, func() error { | 28 return d.mutation(keys, func() error { |
27 return d.RawInterface.DeleteMulti(keys, cb) | 29 return d.RawInterface.DeleteMulti(keys, cb) |
28 }) | 30 }) |
29 } | 31 } |
30 | 32 |
31 func (d *dsCache) PutMulti(keys []*ds.Key, vals []ds.PropertyMap, cb ds.NewKeyCB
) error { | 33 func (d *dsCache) PutMulti(keys []*ds.Key, vals []ds.PropertyMap, cb ds.NewKeyCB
) error { |
32 return d.mutation(keys, func() error { | 34 return d.mutation(keys, func() error { |
33 return d.RawInterface.PutMulti(keys, vals, cb) | 35 return d.RawInterface.PutMulti(keys, vals, cb) |
34 }) | 36 }) |
35 } | 37 } |
36 | 38 |
37 func (d *dsCache) GetMulti(keys []*ds.Key, metas ds.MultiMetaGetter, cb ds.GetMu
ltiCB) error { | 39 func (d *dsCache) GetMulti(keys []*ds.Key, metas ds.MultiMetaGetter, cb ds.GetMu
ltiCB) error { |
38 lockItems, nonce := d.mkRandLockItems(keys, metas) | 40 lockItems, nonce := d.mkRandLockItems(keys, metas) |
39 if len(lockItems) == 0 { | 41 if len(lockItems) == 0 { |
40 return d.RawInterface.GetMulti(keys, metas, cb) | 42 return d.RawInterface.GetMulti(keys, metas, cb) |
41 } | 43 } |
42 | 44 |
43 » if err := d.mc.AddMulti(lockItems); err != nil { | 45 » if err := mc.Add(d.c, lockItems...); err != nil { |
44 // Ignore this error. Either we couldn't add them because they e
xist | 46 // Ignore this error. Either we couldn't add them because they e
xist |
45 // (so, not an issue), or because memcache is having sad times (
in which | 47 // (so, not an issue), or because memcache is having sad times (
in which |
46 » » // case we'll see so in the GetMulti which immediately follows t
his). | 48 » » // case we'll see so in the Get which immediately follows this). |
47 } | 49 } |
48 » if err := errors.Filter(d.mc.GetMulti(lockItems), memcache.ErrCacheMiss)
; err != nil { | 50 » if err := errors.Filter(mc.Get(d.c, lockItems...), mc.ErrCacheMiss); err
!= nil { |
49 (log.Fields{log.ErrorKey: err}).Debugf( | 51 (log.Fields{log.ErrorKey: err}).Debugf( |
50 » » » d.c, "dscache: GetMulti: memcache.GetMulti") | 52 » » » d.c, "dscache: GetMulti: memcache.Get") |
51 } | 53 } |
52 | 54 |
53 p := makeFetchPlan(d.c, d.aid, d.ns, &facts{keys, metas, lockItems, nonc
e}) | 55 p := makeFetchPlan(d.c, d.aid, d.ns, &facts{keys, metas, lockItems, nonc
e}) |
54 | 56 |
55 if !p.empty() { | 57 if !p.empty() { |
56 // looks like we have something to pull from datastore, and mayb
e some work | 58 // looks like we have something to pull from datastore, and mayb
e some work |
57 // to save stuff back to memcache. | 59 // to save stuff back to memcache. |
58 | 60 |
59 » » toCas := []memcache.Item{} | 61 » » toCas := []mc.Item{} |
60 j := 0 | 62 j := 0 |
61 err := d.RawInterface.GetMulti(p.toGet, p.toGetMeta, func(pm ds.
PropertyMap, err error) error { | 63 err := d.RawInterface.GetMulti(p.toGet, p.toGetMeta, func(pm ds.
PropertyMap, err error) error { |
62 i := p.idxMap[j] | 64 i := p.idxMap[j] |
63 toSave := p.toSave[j] | 65 toSave := p.toSave[j] |
64 j++ | 66 j++ |
65 | 67 |
66 data := []byte(nil) | 68 data := []byte(nil) |
67 | 69 |
68 // true: save entity to memcache | 70 // true: save entity to memcache |
69 // false: lock entity in memcache forever | 71 // false: lock entity in memcache forever |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
102 } | 104 } |
103 toCas = append(toCas, toSave) | 105 toCas = append(toCas, toSave) |
104 } | 106 } |
105 return nil | 107 return nil |
106 }) | 108 }) |
107 if err != nil { | 109 if err != nil { |
108 return err | 110 return err |
109 } | 111 } |
110 if len(toCas) > 0 { | 112 if len(toCas) > 0 { |
111 // we have entries to save back to memcache. | 113 // we have entries to save back to memcache. |
112 » » » if err := d.mc.CompareAndSwapMulti(toCas); err != nil { | 114 » » » if err := mc.CompareAndSwap(d.c, toCas...); err != nil { |
113 (log.Fields{log.ErrorKey: err}).Debugf( | 115 (log.Fields{log.ErrorKey: err}).Debugf( |
114 » » » » » d.c, "dscache: GetMulti: memcache.Compar
eAndSwapMulti") | 116 » » » » » d.c, "dscache: GetMulti: memcache.Compar
eAndSwap") |
115 } | 117 } |
116 } | 118 } |
117 } | 119 } |
118 | 120 |
119 // finally, run the callback for all of the decoded items and the errors
, | 121 // finally, run the callback for all of the decoded items and the errors
, |
120 // if any. | 122 // if any. |
121 for i, dec := range p.decoded { | 123 for i, dec := range p.decoded { |
122 if err := cb(dec, p.lme.GetOne(i)); err != nil { | 124 if err := cb(dec, p.lme.GetOne(i)); err != nil { |
123 return err | 125 return err |
124 } | 126 } |
(...skipping 10 matching lines...) Expand all Loading... |
135 if err == nil { | 137 if err == nil { |
136 err = txnState.apply(d.supportContext) | 138 err = txnState.apply(d.supportContext) |
137 } | 139 } |
138 return err | 140 return err |
139 }, opts) | 141 }, opts) |
140 if err == nil { | 142 if err == nil { |
141 txnState.release(d.supportContext) | 143 txnState.release(d.supportContext) |
142 } | 144 } |
143 return err | 145 return err |
144 } | 146 } |
OLD | NEW |