Example #1
0
// 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
}
Example #2
0
// AdjustShards increases the number of shards for the named counter to n.
// It will never decrease the number of shards.
func AdjustShards(c context.Context, valName string, n int) error {
	ckey := datastore.NewKey(c, dsKindNumShards, valName, 0, nil)
	return datastore.RunInTransaction(c, func(c context.Context) error {
		shardsTotal := dsu.WrapInt{}
		mod := false
		err := datastore.Get(c, ckey, &shardsTotal)
		if err == datastore.ErrNoSuchEntity {
			shardsTotal.I = n
			mod = true
		} else if err != nil {
			return err
		}
		if shardsTotal.I < n {
			shardsTotal.I = n
			mod = true
		}
		if mod {
			_, err = datastore.Put(c, ckey, &shardsTotal)
		}
		return err
	}, nil)
}
Example #3
0
// AdjustShards increases the number of shards for the named counter to n.
// It will never decrease the number of shards.
func AdjustShards(c appengine.Context, valName string, n int) error {
	ckey := datastore.NewKey(c, dsKindNumShards, valName, 0, nil)
	return datastore.RunInTransaction(c, func(c appengine.Context) error {
		wNumShards := dsu.WrapInt{}
		mod := false
		err := datastore.Get(c, ckey, &wNumShards)
		if err == datastore.ErrNoSuchEntity {
			wNumShards.I = defaultNumShards
			mod = true
		} else if err != nil {
			return err
		}
		if wNumShards.I < n {
			wNumShards.I = n
			mod = true
		}
		if mod {
			_, err = datastore.Put(c, ckey, &wNumShards)
		}
		return err
	}, nil)
}