| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 package memory | 5 package memory |
| 6 | 6 |
| 7 import ( | 7 import ( |
| 8 "errors" | 8 "errors" |
| 9 "sync" | 9 "sync" |
| 10 | 10 |
| 11 "golang.org/x/net/context" | 11 "golang.org/x/net/context" |
| 12 | 12 |
| 13 » "infra/gae/libs/gae" | 13 » "appengine/datastore" |
| 14 ) | 14 ) |
| 15 | 15 |
| 16 type memContextObj interface { | 16 type memContextObj interface { |
| 17 sync.Locker | 17 sync.Locker |
| 18 canApplyTxn(m memContextObj) bool | 18 canApplyTxn(m memContextObj) bool |
| 19 applyTxn(c context.Context, m memContextObj) | 19 applyTxn(c context.Context, m memContextObj) |
| 20 | 20 |
| 21 endTxn() | 21 endTxn() |
| 22 » mkTxn(*gae.DSTransactionOptions) (memContextObj, error) | 22 » mkTxn(*datastore.TransactionOptions) (memContextObj, error) |
| 23 } | 23 } |
| 24 | 24 |
| 25 type memContext []memContextObj | 25 type memContext []memContextObj |
| 26 | 26 |
| 27 var _ = memContextObj((memContext)(nil)) | 27 var _ = memContextObj((memContext)(nil)) |
| 28 | 28 |
| 29 func newMemContext() memContext { | 29 func newMemContext() memContext { |
| 30 return memContext{ | 30 return memContext{ |
| 31 newTaskQueueData(), | 31 newTaskQueueData(), |
| 32 newDataStoreData(), | 32 newDataStoreData(), |
| (...skipping 22 matching lines...) Expand all Loading... |
| 55 m[i].Unlock() | 55 m[i].Unlock() |
| 56 } | 56 } |
| 57 } | 57 } |
| 58 | 58 |
| 59 func (m memContext) endTxn() { | 59 func (m memContext) endTxn() { |
| 60 for _, itm := range m { | 60 for _, itm := range m { |
| 61 itm.endTxn() | 61 itm.endTxn() |
| 62 } | 62 } |
| 63 } | 63 } |
| 64 | 64 |
| 65 func (m memContext) mkTxn(o *gae.DSTransactionOptions) (memContextObj, error) { | 65 func (m memContext) mkTxn(o *datastore.TransactionOptions) (memContextObj, error
) { |
| 66 ret := make(memContext, len(m)) | 66 ret := make(memContext, len(m)) |
| 67 for i, itm := range m { | 67 for i, itm := range m { |
| 68 newItm, err := itm.mkTxn(o) | 68 newItm, err := itm.mkTxn(o) |
| 69 if err != nil { | 69 if err != nil { |
| 70 return nil, err | 70 return nil, err |
| 71 } | 71 } |
| 72 ret[i] = newItm | 72 ret[i] = newItm |
| 73 } | 73 } |
| 74 return ret, nil | 74 return ret, nil |
| 75 } | 75 } |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 130 // a couple ways, for example. | 130 // a couple ways, for example. |
| 131 // | 131 // |
| 132 // It really should have been appengine.Context.RunInTransaction(func(tc...)), | 132 // It really should have been appengine.Context.RunInTransaction(func(tc...)), |
| 133 // but because it's not, this method is on dsImpl instead to mirror the official | 133 // but because it's not, this method is on dsImpl instead to mirror the official |
| 134 // API. | 134 // API. |
| 135 // | 135 // |
| 136 // The fake implementation also differs from the real implementation because the | 136 // The fake implementation also differs from the real implementation because the |
| 137 // fake TaskQueue is NOT backed by the fake Datastore. This is done to make the | 137 // fake TaskQueue is NOT backed by the fake Datastore. This is done to make the |
| 138 // test-access API for TaskQueue better (instead of trying to reconstitute the | 138 // test-access API for TaskQueue better (instead of trying to reconstitute the |
| 139 // state of the task queue from a bunch of datastore accesses). | 139 // state of the task queue from a bunch of datastore accesses). |
| 140 func (d *dsImpl) RunInTransaction(f func(context.Context) error, o *gae.DSTransa
ctionOptions) error { | 140 func (d *dsImpl) RunInTransaction(f func(context.Context) error, o *datastore.Tr
ansactionOptions) error { |
| 141 curMC := cur(d.c) | 141 curMC := cur(d.c) |
| 142 | 142 |
| 143 txnMC, err := curMC.mkTxn(o) | 143 txnMC, err := curMC.mkTxn(o) |
| 144 if err != nil { | 144 if err != nil { |
| 145 return err | 145 return err |
| 146 } | 146 } |
| 147 | 147 |
| 148 defer func() { | 148 defer func() { |
| 149 txnMC.Lock() | 149 txnMC.Lock() |
| 150 defer txnMC.Unlock() | 150 defer txnMC.Unlock() |
| 151 | 151 |
| 152 txnMC.endTxn() | 152 txnMC.endTxn() |
| 153 }() | 153 }() |
| 154 | 154 |
| 155 if err = f(context.WithValue(d.c, memContextKey, txnMC)); err != nil { | 155 if err = f(context.WithValue(d.c, memContextKey, txnMC)); err != nil { |
| 156 return err | 156 return err |
| 157 } | 157 } |
| 158 | 158 |
| 159 txnMC.Lock() | 159 txnMC.Lock() |
| 160 defer txnMC.Unlock() | 160 defer txnMC.Unlock() |
| 161 | 161 |
| 162 if curMC.canApplyTxn(txnMC) { | 162 if curMC.canApplyTxn(txnMC) { |
| 163 curMC.applyTxn(d.c, txnMC) | 163 curMC.applyTxn(d.c, txnMC) |
| 164 } else { | 164 } else { |
| 165 » » return gae.ErrDSConcurrentTransaction | 165 » » return datastore.ErrConcurrentTransaction |
| 166 } | 166 } |
| 167 return nil | 167 return nil |
| 168 } | 168 } |
| OLD | NEW |