Chromium Code Reviews| Index: appengine/tumble/tumble.go |
| diff --git a/appengine/tumble/tumble.go b/appengine/tumble/tumble.go |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..6b95190c04c526f54674a3152f79df4f72d3c225 |
| --- /dev/null |
| +++ b/appengine/tumble/tumble.go |
| @@ -0,0 +1,61 @@ |
| +// 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 tumble |
| + |
| +import ( |
| + "fmt" |
| + |
| + "github.com/luci/gae/filter/txnBuf" |
| + "github.com/luci/gae/service/datastore" |
| + "golang.org/x/net/context" |
| +) |
| + |
| +// EnterTransaction is the method to use when doing transactional operations |
| +// in the tumble ecosystem. It allows work to be done in the entity group |
| +// specified by `fromRoot`, and any returned Mutation objects will be |
| +// transactionally queued for the tumble backend. |
| +// |
| +// Usually this is called from your application's handlers to begin a tumble |
| +// state machine as a result of some API interaction. |
| +func EnterTransaction(c context.Context, fromRoot *datastore.Key, f func(context.Context) ([]Mutation, error)) error { |
| + shardSet, _, err := enterTransactionInternal(txnBuf.FilterRDS(c), fromRoot, f) |
| + if err != nil { |
| + return err |
| + } |
| + fireTasks(c, shardSet) |
| + return nil |
| +} |
| + |
| +func enterTransactionInternal(c context.Context, fromRoot *datastore.Key, f func(context.Context) ([]Mutation, error)) (map[uint64]struct{}, uint, error) { |
|
iannucci
2015/10/10 17:51:53
split this up so that when we're in the process lo
|
| + if fromRoot == nil { |
| + return nil, 0, fmt.Errorf("tumble: Passing nil as fromRoot is illegal") |
| + } |
| + |
| + shardSet := map[uint64]struct{}(nil) |
| + numNewMuts := uint(0) |
| + |
| + err := datastore.Get(c).RunInTransaction(func(c context.Context) error { |
| + // do a Get on the fromRoot to ensure that this transaction is associated |
| + // with that entity group. |
| + _ = datastore.Get(c).Get(datastore.PropertyMap{ |
| + "$key": {datastore.MkPropertyNI(fromRoot)}, |
|
Vadim Sh.
2015/10/12 20:05:14
is it how hypothetical Exists(key) looks?
iannucci
2015/10/13 02:39:46
Yeah, it's kinda ugly. Do you think it's worth add
Vadim Sh.
2015/10/13 02:46:20
Yes.
We actually needed this in isolate server (
|
| + }) |
| + |
| + muts, err := f(c) |
| + if err != nil { |
| + return err |
| + } |
| + |
| + numNewMuts = uint(len(muts)) |
| + shardSet, err = putMutations(c, fromRoot, muts) |
| + |
| + return err |
| + }, nil) |
| + if err != nil { |
| + return nil, 0, err |
| + } |
| + |
| + return shardSet, numNewMuts, nil |
| +} |