Ejemplo n.º 1
0
// CAS does an atomic compare-and-swap on a counter.
func (Example) CAS(c context.Context, r *CASReq) (err error) {
	success := false
	c = prod.Use(c)
	err = rdsS.Get(c).RunInTransaction(func(c context.Context) error {
		rds := rdsS.Get(c)
		key := rds.NewKey("Counter", r.Name, 0, nil)
		ctr := &Counter{}
		pls := rdsS.GetPLS(ctr)
		if err := rds.Get(key, pls); err != nil {
			return err
		}
		if ctr.Val == r.OldVal {
			success = true
			ctr.Val = r.NewVal
			_, err := rds.Put(key, pls)
			return err
		}
		success = false
		return nil
	}, nil)
	if err == nil && !success {
		err = endpoints.ConflictError
	}
	return
}
Ejemplo n.º 2
0
// CurrentValue gets the current value of a counter (duh)
func (Example) CurrentValue(c context.Context, r *CurrentValueReq) (rsp *CurrentValueRsp, err error) {
	c = prod.Use(c)
	rds := rdsS.Get(c)

	key := rds.NewKey("Counter", r.Name, 0, nil)
	ctr := &Counter{}
	if err = rds.Get(key, rdsS.GetPLS(ctr)); err != nil {
		return
	}

	rsp = &CurrentValueRsp{ctr.Val}
	return
}
Ejemplo n.º 3
0
// List returns a list of all the counters. Note that it's very poorly
// implemented! It's completely unpaged. I don't care :).
func (Example) List(c context.Context) (rsp *ListRsp, err error) {
	rds := rawdatastore.Get(prod.Use(c))
	rsp = &ListRsp{}
	dst := []rawdatastore.PropertyMap{}
	_, err = rds.GetAll(rds.NewQuery("Counter"), &dst)
	if err != nil {
		return
	}
	rsp.Counters = make([]Counter, len(dst))
	for i, m := range dst {
		if err = rawdatastore.GetPLS(rsp.Counters[i]).Load(m); err != nil {
			return
		}
	}
	return
}
Ejemplo n.º 4
0
// Add adds a value to the current counter, and returns the old+new values. It
// may cause a counter to come into existance.
func (Example) Add(c context.Context, r *AddReq) (rsp *AddRsp, err error) {
	rsp = &AddRsp{}

	c = prod.Use(c)
	err = dstore.Get(c).RunInTransaction(func(c context.Context) error {
		ds := dstore.Get(c)
		ctr := &Counter{Name: r.Name}
		if err := ds.Get(ctr); err != nil && err != dstore.ErrNoSuchEntity {
			return err
		}
		rsp.Prev = ctr.Val
		ctr.Val += r.Delta
		rsp.Cur = ctr.Val
		return ds.Put(ctr)
	}, nil)
	return
}
Ejemplo n.º 5
0
// Add adds a value to the current counter, and returns the old+new values. It
// may cause a counter to come into existance.
func (Example) Add(c context.Context, r *AddReq) (rsp *AddRsp, err error) {
	rsp = &AddRsp{}

	c = prod.Use(c)
	err = rdsS.Get(c).RunInTransaction(func(c context.Context) error {
		rds := rdsS.Get(c)
		ctr := &Counter{}
		pls := rdsS.GetPLS(ctr)
		key := rds.NewKey("Counter", r.Name, 0, nil)
		if err := rds.Get(key, pls); err != nil && err != rdsS.ErrNoSuchEntity {
			return err
		}
		rsp.Prev = ctr.Val
		ctr.Val += r.Delta
		rsp.Cur = ctr.Val
		_, err := rds.Put(key, pls)
		return err
	}, nil)
	return
}
Ejemplo n.º 6
0
// CAS does an atomic compare-and-swap on a counter.
func (Example) CAS(c context.Context, r *CASReq) (err error) {
	success := false
	c = prod.Use(c)
	err = dstore.Get(c).RunInTransaction(func(c context.Context) error {
		ds := dstore.Get(c)
		ctr := &Counter{Name: r.Name}
		if err := ds.Get(ctr); err != nil {
			return err
		}
		if ctr.Val == r.OldVal {
			success = true
			ctr.Val = r.NewVal
			return ds.Put(ctr)
		}
		success = false
		return nil
	}, nil)
	if err == nil && !success {
		err = endpoints.ConflictError
	}
	return
}
Ejemplo n.º 7
0
// List returns a list of all the counters. Note that it's very poorly
// implemented! It's completely unpaged. I don't care :).
func (Example) List(c context.Context) (rsp *ListRsp, err error) {
	ds := dstore.Get(prod.Use(c))
	rsp = &ListRsp{}
	err = ds.GetAll(ds.NewQuery("Counter"), &rsp.Counters)
	return
}