func handler(res http.ResponseWriter, req *http.Request) { ctx := appengine.NewContext(req) globalCounter, err := memcache.Increment(ctx, "globalCounter", 1, 0) if err != nil { http.Error(res, "Server Error", http.StatusInternalServerError) log.Errorf(ctx, err.Error()) } currentUser := user.Current(ctx) userCounter, err := memcache.Increment(ctx, currentUser.Email+"-Counter", 1, 0) if err != nil { http.Error(res, "Server Error", http.StatusInternalServerError) log.Errorf(ctx, err.Error()) } fmt.Fprintf(res, "Hello World! You are visitor #%d, and you have visited %d times!", globalCounter, userCounter) }
func index(res http.ResponseWriter, req *http.Request) { if req.URL.Path != "/" { http.NotFound(res, req) return } ctx := appengine.NewContext(req) u := user.Current(ctx) globalCount, _ := memcache.Increment(ctx, "GLOBAL", 1, 0) userCount, _ := memcache.Increment(ctx, u.Email+".COUNTER", 1, 0) fmt.Fprintln(res, "Global", globalCount) fmt.Fprintln(res, "User", userCount) }
// Increment increments the named counter. func Increment(c context.Context, valName string) error { // Get counter config. shardsTotal := dsu.WrapInt{} dsu.McacheGet(c, mcKeyShardsTotal(valName), &shardsTotal) if shardsTotal.I < 1 { ckey := datastore.NewKey(c, dsKindNumShards, mcKeyShardsTotal(valName), 0, nil) errTx := datastore.RunInTransaction(c, func(c context.Context) error { err := datastore.Get(c, ckey, &shardsTotal) if err == datastore.ErrNoSuchEntity { shardsTotal.I = defaultNumShards _, err = datastore.Put(c, ckey, &shardsTotal) } return err }, nil) if errTx != nil { return errTx } dsu.McacheSet(c, mcKeyShardsTotal(valName), dsu.WrapInt{shardsTotal.I}) } // pick random counter and increment it errTx := datastore.RunInTransaction(c, func(c context.Context) error { shardId := rand.Intn(shardsTotal.I) dsKey := datastore.NewKey(c, dsKindShard, keySingleShard(valName, shardId), 0, nil) var sd WrapShardData err := datastore.Get(c, dsKey, &sd) // A missing entity and a present entity will both work. if err != nil && err != datastore.ErrNoSuchEntity { return err } sd.Name = valName sd.ShardId = shardId sd.I++ _, err = datastore.Put(c, dsKey, &sd) if ll > 2 { aelog.Infof(c, "ds put %v %v", dsKey, sd) } return err }, nil) if errTx != nil { return errTx } memcache.Increment(c, mcKey(valName), 1, 0) // collect number of updates // per valName per instance in memory // for every interval of 10 minutes // // a batch job checks if the number of shards should be increased or decreased // and truncates this map updateSamplingFrequency[valName+util.TimeMarker()[:len("2006-01-02 15:0")]] += 1 return nil }
func counter(res http.ResponseWriter, req *http.Request) { ctx := appengine.NewContext(req) // create the item // func Increment(c appengine.Context, key string, delta int64, initialValue uint64) (newValue uint64, err error) counter, err := memcache.Increment(ctx, "counter", 1, 0) if err != nil { http.Error(res, "counter didn't work", 500) return } fmt.Fprint(res, counter) }
func handle(w http.ResponseWriter, r *http.Request) { // [START example] w.Header().Set("Content-Type", "text/plain") c := appengine.NewContext(r) who := "nobody" item, err := memcache.Get(c, "who") if err == nil { who = string(item.Value) } else if err != memcache.ErrCacheMiss { http.Error(w, err.Error(), http.StatusInternalServerError) return } fmt.Fprintf(w, "Previously incremented by %s\n", who) memcache.Set(c, &memcache.Item{ Key: "who", Value: []byte("Go"), }) count, _ := memcache.Increment(c, "count", 1, 0) fmt.Fprintf(w, "Count incremented by Go = %d\n", count) // [END example] }
func TestPluginUsage(t *testing.T) { c, closer, err := aetest.NewContext() if err != nil { t.Fatal(err) } defer closer() parentKey := datastore.NewKey(c, "Test", "T", 0, nil) { // put for Datastore src := &e.Sample{"Foo!"} key := datastore.NewIncompleteKey(c, "Sample", parentKey) _, err = datastore.Put(c, key, src) if err != nil { t.Fatal(err) } _, err = memcache.Increment(c, "counter", 1, 0) // shift memcache counter if err != nil { t.Fatal(err) } } builder := e.NewSampleQueryBuilder() mp, ok := builder.Plugin().(*e.MemcacheQueryPlugin) if !ok { t.Fatal("Plugin is not MemcacheQueryPlugin") } memcacheCounter, err := memcache.Increment(c, "counter", 0, 0) if err != nil { t.Fatal(err) } mp.AddCounter(memcacheCounter) builder.Ancestor(parentKey).Foo.GreaterThan("Fo").Limit(3) if str := mp.QueryString(); str != `k=Sample:1:!a=/Test,T:?Foo>"Fo":!l=3` { t.Fatalf("unexpected: %s", str) } { // get from Memcache var list []*e.Sample _, err = memcache.Gob.Get(c, mp.QueryString(), &list) if err == memcache.ErrCacheMiss { // continue } else if err != nil { t.Fatal(err) } else { t.Log(list) return } } { // get from Datastore iter := builder.Query().Run(c) var list []*e.Sample for { src := &e.Sample{} _, err = iter.Next(src) if err == datastore.Done { break } else if err != nil { t.Fatal(err) } list = append(list, src) } // put for Memcache err = memcache.Gob.Set(c, &memcache.Item{ Key: mp.QueryString(), Object: list, }) if err != nil { t.Fatal(err) } if len(list) != 1 { t.Fatalf("unexpected %d", len(list)) } } { // get from Memcache var list []*e.Sample _, err = memcache.Gob.Get(c, mp.QueryString(), &list) if err == memcache.ErrCacheMiss { t.Fatalf("query result is not in memcache") } else if err != nil { t.Fatal(err) } else { t.Log(list) } } }
func (mc *gaeMemcache) inc(c context.Context, key string, delta int64, initial uint64) (uint64, error) { return memcache.Increment(c, key, delta, initial) }
func (m mcImpl) Increment(key string, delta int64, initialValue *uint64) (uint64, error) { if initialValue == nil { return memcache.IncrementExisting(m.aeCtx, key, delta) } return memcache.Increment(m.aeCtx, key, delta, *initialValue) }