Exemplo n.º 1
0
// CheckAndSet put a value with a key into the Cache,
// ONLY IF it has no newer values with, i.e. no update since, a given serial.
// It takes key, value parameters as an interface{} type and performs marshal for them.
// If succeed, it returns a serial number(an unix timestamp in millis) for the value.
// If a value of newer serial already exists, CheckAndSet would fail with ErrSetFailed.
func (c *Cache) CheckAndSet(key interface{}, val interface{}, oserial int64) (int64, error) {
	bkey, err := c.options.Marshal(key)
	if err != nil {
		return 0, err
	}
	client, disconnect, _, err := c.connector.Connect(bkey)
	if err != nil {
		return 0, err
	}
	defer func() {
		if disconnect != nil {
			disconnect()
		}
	}()

	bval, err := c.options.Marshal(val)
	if err != nil {
		return 0, err
	}
	nserial := getSerial()
	resp := util.LuaEval(client, luaForCheckAndSet, 1, bkey, bval, oserial, nserial, c.options.Expiration.Seconds())
	if resp.Err != nil {
		return 0, resp.Err
	}
	if resp.IsType(redis.Nil) {
		return 0, ErrSetFailed
	}

	atomic.AddInt64(&c.loads, 1)
	return nserial, nil
}
Exemplo n.º 2
0
// Get returns a cached value using bound Connector.
// It takes key, value parameters as an interface{} type and performs marshal/unmarshal for them.
func (c *Cache) Get(key interface{}, val interface{}) (int64, error) {
	bkey, err := c.options.Marshal(key)
	if err != nil {
		return 0, err
	}
	client, disconnect, validSince, err := c.connector.Connect(bkey)
	if err != nil {
		return 0, err
	}
	defer func() {
		if disconnect != nil {
			disconnect()
		}
	}()

	resp := util.LuaEval(client, luaForGet, 1, bkey, validSince)
	if resp.Err != nil {
		return 0, resp.Err
	}
	if resp.IsType(redis.Nil) {
		atomic.AddInt64(&c.misses, 1)
		return 0, ErrNoKey
	}

	if resp.IsType(redis.Array) {
		if res, err := resp.Array(); err == nil && len(res) == 2 {
			if res[0].IsType(redis.BulkStr) && res[1].IsType(redis.Int) {
				bval, _ := res[0].Bytes()
				serial, _ := res[1].Int64()
				if err := c.options.Unmarshal(bval, val); err != nil {
					return 0, err
				}
				atomic.AddInt64(&c.hits, 1)
				return serial, nil
			}
		}
	}
	return 0, ErrRESPParse
}