| 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 dumbCounter | |
| 6 | |
| 7 import ( | |
| 8 "github.com/GoogleCloudPlatform/go-endpoints/endpoints" | |
| 9 dstore "github.com/luci/gae/service/datastore" | |
| 10 "golang.org/x/net/context" | |
| 11 ) | |
| 12 | |
| 13 // CASReq is the input for the CAS RPC | |
| 14 type CASReq struct { | |
| 15 Name string `endpoints:"required"` | |
| 16 | |
| 17 OldVal int64 `json:",string"` | |
| 18 NewVal int64 `json:",string"` | |
| 19 } | |
| 20 | |
| 21 // CAS does an atomic compare-and-swap on a counter. | |
| 22 func (e *Example) CAS(c context.Context, r *CASReq) (err error) { | |
| 23 c, err = e.Use(c, casMethodInfo) | |
| 24 if err != nil { | |
| 25 return | |
| 26 } | |
| 27 | |
| 28 success := false | |
| 29 err = dstore.Get(c).RunInTransaction(func(c context.Context) error { | |
| 30 ds := dstore.Get(c) | |
| 31 ctr := &Counter{Name: r.Name} | |
| 32 if err := ds.Get(ctr); err != nil { | |
| 33 return err | |
| 34 } | |
| 35 if ctr.Val == r.OldVal { | |
| 36 success = true | |
| 37 ctr.Val = r.NewVal | |
| 38 return ds.Put(ctr) | |
| 39 } | |
| 40 success = false | |
| 41 return nil | |
| 42 }, nil) | |
| 43 if err == nil && !success { | |
| 44 err = endpoints.ConflictError | |
| 45 } | |
| 46 return | |
| 47 } | |
| 48 | |
| 49 var casMethodInfo = &endpoints.MethodInfo{ | |
| 50 Path: "counter/{Name}/cas", | |
| 51 Desc: "Compare and swap a counter value", | |
| 52 } | |
| OLD | NEW |