Beispiel #1
0
// Create a bucket.
func (s *Storage) Create(name string, capacity uint, rate time.Duration) (leakybucket.Bucket, error) {
	conn := s.pool.Get()
	defer conn.Close()

	if count, err := redis.Uint64(conn.Do("GET", name)); err != nil {
		if err != redis.ErrNil {
			return nil, err
		}
		// return a standard bucket if key was not found
		return &bucket{
			name:      name,
			capacity:  capacity,
			remaining: capacity,
			reset:     time.Now().Add(rate),
			rate:      rate,
			pool:      s.pool,
		}, nil
	} else if ttl, err := redis.Int64(conn.Do("PTTL", name)); err != nil {
		return nil, err
	} else {
		b := &bucket{
			name:      name,
			capacity:  capacity,
			remaining: capacity - min(capacity, uint(count)),
			reset:     time.Now().Add(time.Duration(ttl * millisecond)),
			rate:      rate,
			pool:      s.pool,
		}
		return b, nil
	}
}
Beispiel #2
0
// scanUint converts a reply from redis into a uint and scans the value into v.
func scanUint(reply interface{}, v *uint) error {
	if v == nil {
		return fmt.Errorf("jobs: In scanUint: argument v was nil")
	}
	val, err := redis.Uint64(reply, nil)
	if err != nil {
		return fmt.Errorf("jobs: In scanUint: Could not convert %v of type %T to uint.", reply, reply)
	}
	(*v) = uint(val)
	return nil
}
Beispiel #3
0
func (km *KeyManager) getNewIdIdx(idx int) (uint64, error) {
	conn := km.idRedis[idx].Get()
	defer conn.Close()
	r, err := conn.Do("INCR", km.idKey)
	if err != nil {
		return 0, err
	}
	id, err := redis.Uint64(r, err)
	if err != nil {
		return 0, err
	}
	return id*2 + uint64(idx), nil
}
Beispiel #4
0
// Add to the bucket.
func (b *bucket) Add(amount uint) (leakybucket.BucketState, error) {
	conn := b.pool.Get()
	defer conn.Close()

	if count, err := redis.Uint64(conn.Do("GET", b.name)); err != nil {
		// handle the key not being set
		if err == redis.ErrNil {
			b.remaining = b.capacity
		} else {
			return b.State(), err
		}
	} else {
		b.remaining = b.capacity - min(uint(count), b.capacity)
	}

	if amount > b.remaining {
		b.updateOldReset()
		return b.State(), leakybucket.ErrorFull
	}

	// Go y u no have Milliseconds method? Why only Seconds and Nanoseconds?
	expiry := int(b.rate.Nanoseconds() / millisecond)

	count, err := redis.Uint64(conn.Do("INCRBY", b.name, amount))
	if err != nil {
		return b.State(), err
	} else if uint(count) == amount {
		if _, err := conn.Do("PEXPIRE", b.name, expiry); err != nil {
			return b.State(), err
		}
	}

	b.updateOldReset()

	// Ensure we can't overflow
	b.remaining = b.capacity - min(uint(count), b.capacity)
	return b.State(), nil
}
Beispiel #5
0
func LoadFrame(conn redis.Conn, header *SBFHeader, id uint16) (*SBFFrame, error) {
	// key := SBF_NAME + ":count:" + header.Refer + ":1"
	key := fmt.Sprintf("%s:count:%s:%d", SBF_NAME, header.Refer, id)
	frame := new(SBFFrame)
	frame.Key = key
	frame.Refer = header.Refer
	frame.Count = 0
	frame.frameDataRange(header, id)
	if count, err := redis.Uint64(conn.Do("GET", key)); err == nil {
		frame.Count = uint32(count)
	} else if err != redis.ErrNil {
		return nil, err
	}
	return frame, nil
}
Beispiel #6
0
// object must be a pointer to a settable object
func (c *redisStore) save(mv *metaValue) error {
	if mv.getPrimaryKey() == 0 {
		keyName := fmt.Sprintf("%v:%v", c.appPrefix, mv.mt.t.Name())
		newId, err := redis.Uint64(c.conn.Do("INCR", keyName))
		if err != nil {
			return err
		}
		mv.setPrimaryKey(newId)
	}

	key := mv.getKeyString(c.appPrefix)
	args := []interface{}{key}

	v := mv.p.Elem()
	for i := 0; i < mv.mt.t.NumField(); i++ {
		if mv.mt.id == i {
			continue
		}

		name := mv.mt.t.Field(i).Name
		value := v.Field(i).Interface()

		if mv.mt.t.Field(i).Type == timeType {
			timev, ok := value.(time.Time)
			if !ok {
				return newInternalError(nil, "Shouldn't happen.")
			}
			bs, err := timev.MarshalText()
			if err != nil {
				return newInternalError(err, "Shouldn't happen.")
			}
			value = bs
		}

		args = append(args, name, value)
	}

	_, err := c.conn.Do("HMSET", args...)
	if err != nil {
		return err
	}
	fmt.Printf("Saved %v to %v.\n", args, key)

	return nil
}
Beispiel #7
0
// Count counts the number of models that would be returned by the query without
// actually retreiving the models themselves. Count will also return the first
// error that occured during the lifetime of the query object (if any).
// Otherwise, the second return value will be nil.
func (q *Query) Count() (uint, error) {
	if q.hasError() {
		return 0, q.err
	}
	if !q.hasFilters() {
		// Just return the number of ids in the all index set
		conn := q.pool.NewConn()
		defer conn.Close()
		count64, err := redis.Uint64(conn.Do("SCARD", q.collection.spec.indexKey()))
		if err != nil {
			return 0, nil
		}
		count := uint(count64)
		// Apply math to take into account limit and offset
		switch {
		case !q.hasLimit() && !q.hasOffset():
			return count, nil
		default:
			if q.hasOffset() {
				count = count - q.offset
			}
			if q.hasLimit() && q.limit < count {
				count = q.limit
			}
			return count, nil
		}
	} else {
		// If the query has filters, it is difficult to do any optimizations.
		// Instead we'll just count the number of ids that match the query
		// criteria.
		ids, err := q.Ids()
		if err != nil {
			return 0, err
		}
		return uint(len(ids)), nil
	}
}
Beispiel #8
0
	}
}

// replyConverter represents a function which is capable of converting a redis
// reply to some other type.
type replyConverter func(interface{}) (interface{}, error)

var (
	int64Converter replyConverter = func(in interface{}) (interface{}, error) {
		return redis.Int64(in, nil)
	}
	intConverter replyConverter = func(in interface{}) (interface{}, error) {
		return redis.Int(in, nil)
	}
	uintConverter replyConverter = func(in interface{}) (interface{}, error) {
		v, err := redis.Uint64(in, nil)
		if err != nil {
			return nil, err
		}
		return uint(v), nil
	}
	stringConverter replyConverter = func(in interface{}) (interface{}, error) {
		return redis.String(in, nil)
	}
	bytesConverter replyConverter = func(in interface{}) (interface{}, error) {
		return redis.Bytes(in, nil)
	}
)

// expectSetContains sets an error via t.Errorf if member is not in the set
func expectSetContains(t *testing.T, setName string, member string) {
Beispiel #9
0
		ve(redis.Values(nil, nil)),
		ve([]interface{}(nil), redis.ErrNil),
	},
	{
		"float64(1.0)",
		ve(redis.Float64([]byte("1.0"), nil)),
		ve(float64(1.0), nil),
	},
	{
		"float64(nil)",
		ve(redis.Float64(nil, nil)),
		ve(float64(0.0), redis.ErrNil),
	},
	{
		"uint64(1)",
		ve(redis.Uint64(int64(1), nil)),
		ve(uint64(1), nil),
	},
	{
		"uint64(-1)",
		ve(redis.Uint64(int64(-1), nil)),
		ve(uint64(0), redis.ErrNegativeInt),
	},
}

func TestReply(t *testing.T) {
	for _, rt := range replyTests {
		if rt.actual.err != rt.expected.err {
			t.Errorf("%s returned err %v, want %v", rt.name, rt.actual.err, rt.expected.err)
			continue
		}
Beispiel #10
0
			return redis.Int(r, e)
		},
		"int64": func(r interface{}, e error) (interface{}, error) {
			return redis.Int64(r, e)
		},
		"ints": func(r interface{}, e error) (interface{}, error) {
			return redis.Ints(r, e)
		},
		"string": func(r interface{}, e error) (interface{}, error) {
			return redis.String(r, e)
		},
		"strings": func(r interface{}, e error) (interface{}, error) {
			return redis.Strings(r, e)
		},
		"uint64": func(r interface{}, e error) (interface{}, error) {
			return redis.Uint64(r, e)
		},
		"values": func(r interface{}, e error) (interface{}, error) {
			return redis.Values(r, e)
		},
		"stringmap": func(r interface{}, e error) (interface{}, error) {
			return redis.StringMap(r, e)
		},
	}
)

func (r *RedisTaskConfigQuery) Validate() (err error) {
	for ru, _ := range redisunderstands {
		if r.Type == ru {
			return nil
		}
Beispiel #11
0
func (*RedisStore) Uint64(reply interface{}, err error) (uint64, error) {
	return redis.Uint64(reply, err)
}
Beispiel #12
0
func (v *RedisValue) Uint64() (uint64, error) {
	return redis.Uint64(v.Raw, v.Err)
}