Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#632: Feature: KeepAlive and Timeout Support #745

Closed
wants to merge 12 commits into from
4 changes: 2 additions & 2 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,8 @@ var baseConfig = Config{
}{
Addr: DefaultHost,
Port: DefaultPort,
KeepAlive: int32(300),
Timeout: int32(300),
KeepAlive: int32(30),
Timeout: int32(30),
MaxConn: int32(0),
ShardCronFrequency: 1 * time.Second,
MultiplexerPollTimeout: 100 * time.Millisecond,
Expand Down
4 changes: 4 additions & 0 deletions internal/errors/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,21 @@ const (
ArityErr = "wrong number of arguments for '%s' command"
SyntaxErr = "syntax error"
ExpiryErr = "invalid expire time in '%s' command"
AuthErr = "AUTH failed"
IntOrOutOfRangeErr = "value is not an integer or out of range"
IntOrFloatErr = "value is not an integer or a float"
ValOutOfRangeErr = "value is out of range"
IncrDecrOverflowErr = "increment or decrement would overflow"
ElementPeekErr = "number of elements to peek should be a positive number less than %d"
NoKeyErr = "no such key"
ErrDefault = "-ERR %s"
WrongTypeErr = "-WRONGTYPE Operation against a key holding the wrong kind of value"
WrongTypeHllErr = "-WRONGTYPE Key is not a valid HyperLogLog string value."
InvalidHllErr = "-INVALIDOBJ Corrupted HLL object detected"
WorkerNotFoundErr = "worker with ID %s not found"
JSONPathNotExistErr = "-ERR Path '%s' does not exist"
JSONPathValueTypeErr = "-WRONGTYPE wrong type of path value - expected string but found integer"
InvalidExpireTime = "-ERR invalid expire time"
HashValueNotIntegerErr = "hash value is not an integer"
InternalServerError = "-ERR: Internal server error, unable to process command"
InvalidFloatErr = "-ERR value is not a valid float"
Expand Down
42 changes: 21 additions & 21 deletions internal/eval/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -621,10 +621,10 @@ var (
KeySpecs: KeySpecs{BeginIndex: 1},
}
hkeysCmdMeta = DiceCmdMeta{
Name: "HKEYS",
Info: `HKEYS command is used to retrieve all the keys(or field names) within a hash. Complexity is O(n) where n is the size of the hash.`,
Eval: evalHKEYS,
Arity: 1,
Name: "HKEYS",
Info: `HKEYS command is used to retrieve all the keys(or field names) within a hash. Complexity is O(n) where n is the size of the hash.`,
Eval: evalHKEYS,
Arity: 1,
KeySpecs: KeySpecs{BeginIndex: 1},
}
hsetnxCmdMeta = DiceCmdMeta{
Expand Down Expand Up @@ -918,27 +918,27 @@ var (
Arity: 3,
KeySpecs: KeySpecs{BeginIndex: 1},
}
dumpkeyCMmdMeta=DiceCmdMeta{
Name: "DUMP",
Info: `Serialize the value stored at key in a Redis-specific format and return it to the user.
dumpkeyCMmdMeta = DiceCmdMeta{
Name: "DUMP",
Info: `Serialize the value stored at key in a Redis-specific format and return it to the user.
The returned value can be synthesized back into a Redis key using the RESTORE command.`,
Eval: evalDUMP,
Arity: 1,
KeySpecs: KeySpecs{BeginIndex: 1},
Eval: evalDUMP,
Arity: 1,
KeySpecs: KeySpecs{BeginIndex: 1},
}
restorekeyCmdMeta=DiceCmdMeta{
Name: "RESTORE",
Info: `Serialize the value stored at key in a Redis-specific format and return it to the user.
restorekeyCmdMeta = DiceCmdMeta{
Name: "RESTORE",
Info: `Serialize the value stored at key in a Redis-specific format and return it to the user.
The returned value can be synthesized back into a Redis key using the RESTORE command.`,
Eval: evalRestore,
Arity: 2,
Eval: evalRestore,
Arity: 2,
KeySpecs: KeySpecs{BeginIndex: 1},
}
typeCmdMeta = DiceCmdMeta{
Name: "TYPE",
Info: `Returns the string representation of the type of the value stored at key. The different types that can be returned are: string, list, set, zset, hash and stream.`,
Eval: evalTYPE,
Arity: 1,
Name: "TYPE",
Info: `Returns the string representation of the type of the value stored at key. The different types that can be returned are: string, list, set, zset, hash and stream.`,
Eval: evalTYPE,
Arity: 1,

KeySpecs: KeySpecs{BeginIndex: 1},
}
Expand Down Expand Up @@ -1053,8 +1053,8 @@ func init() {
DiceCmds["PING"] = pingCmdMeta
DiceCmds["ECHO"] = echoCmdMeta
DiceCmds["AUTH"] = authCmdMeta
DiceCmds["DUMP"]=dumpkeyCMmdMeta
DiceCmds["RESTORE"]=restorekeyCmdMeta
DiceCmds["DUMP"] = dumpkeyCMmdMeta
DiceCmds["RESTORE"] = restorekeyCmdMeta
DiceCmds["SET"] = setCmdMeta
DiceCmds["GET"] = getCmdMeta
DiceCmds["MSET"] = msetCmdMeta
Expand Down
132 changes: 66 additions & 66 deletions internal/eval/dump_restore.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,21 @@ import (
)

func evalDUMP(args []string, store *dstore.Store) []byte {
if len(args) < 1 {
return diceerrors.NewErrArity("DUMP")
}
key := args[0]
obj := store.Get(key)
if obj == nil {
return diceerrors.NewErrWithFormattedMessage("nil")
}
serializedValue, err := rdbSerialize(obj)
if err != nil {
return diceerrors.NewErrWithMessage("serialization failed")
}
if len(args) < 1 {
return diceerrors.NewErrArity("DUMP")
}
key := args[0]
obj := store.Get(key)
if obj == nil {
return diceerrors.NewErrWithFormattedMessage("nil")
}

serializedValue, err := rdbSerialize(obj)
if err != nil {
return diceerrors.NewErrWithMessage("serialization failed")
}
encodedResult := base64.StdEncoding.EncodeToString(serializedValue)
return clientio.Encode(encodedResult, false)
return clientio.Encode(encodedResult, false)
}

func evalRestore(args []string, store *dstore.Store) []byte {
Expand All @@ -38,9 +38,9 @@ func evalRestore(args []string, store *dstore.Store) []byte {
}

key := args[0]
ttlStr:=args[1]
ttlStr := args[1]
ttl, _ := strconv.ParseInt(ttlStr, 10, 64)

encodedValue := args[2]
serializedData, err := base64.StdEncoding.DecodeString(encodedValue)
if err != nil {
Expand All @@ -52,23 +52,23 @@ func evalRestore(args []string, store *dstore.Store) []byte {
return diceerrors.NewErrWithMessage("deserialization failed: " + err.Error())
}

newobj:=store.NewObj(obj.Value,ttl,obj.TypeEncoding,obj.TypeEncoding)
var keepttl=true
newobj := store.NewObj(obj.Value, ttl, obj.TypeEncoding, obj.TypeEncoding)
var keepttl = true

if(ttl>0){
if ttl > 0 {
store.Put(key, newobj, dstore.WithKeepTTL(keepttl))
}else{
store.Put(key,obj)
} else {
store.Put(key, obj)
}

return clientio.RespOK
}

func rdbDeserialize(data []byte) (*object.Obj, error) {
if len(data) < 3 {
return nil, errors.New("insufficient data for deserialization")
}
objType := data[1]
objType := data[1]
switch objType {
case 0x00:
return readString(data[2:])
Expand Down Expand Up @@ -104,55 +104,55 @@ func readInt(data []byte) (*object.Obj, error) {
}

func rdbSerialize(obj *object.Obj) ([]byte, error) {
var buf bytes.Buffer
buf.WriteByte(0x09)

switch object.GetType(obj.TypeEncoding) {
case object.ObjTypeString:
str, ok := obj.Value.(string)
if !ok {
return nil, errors.New("invalid string value")
}
buf.WriteByte(0x00)
if err := writeString(&buf, str); err != nil {
return nil, err
}

case object.ObjTypeInt:
intVal, ok := obj.Value.(int64)
if !ok {
return nil, errors.New("invalid integer value")
}
buf.WriteByte(0xC0)
writeInt(&buf, intVal);

default:
return nil, errors.New("unsupported object type")
}

buf.WriteByte(0xFF) // End marker

return appendChecksum(buf.Bytes()), nil
var buf bytes.Buffer
buf.WriteByte(0x09)

switch object.GetType(obj.TypeEncoding) {
case object.ObjTypeString:
str, ok := obj.Value.(string)
if !ok {
return nil, errors.New("invalid string value")
}
buf.WriteByte(0x00)
if err := writeString(&buf, str); err != nil {
return nil, err
}

case object.ObjTypeInt:
intVal, ok := obj.Value.(int64)
if !ok {
return nil, errors.New("invalid integer value")
}
buf.WriteByte(0xC0)
writeInt(&buf, intVal)

default:
return nil, errors.New("unsupported object type")
}

buf.WriteByte(0xFF) // End marker

return appendChecksum(buf.Bytes()), nil
}

func writeString(buf *bytes.Buffer, str string) error {
strLen := uint32(len(str))
if err := binary.Write(buf, binary.BigEndian, strLen); err != nil {
return err
}
buf.WriteString(str)
return nil
strLen := uint32(len(str))
if err := binary.Write(buf, binary.BigEndian, strLen); err != nil {
return err
}
buf.WriteString(str)
return nil
}

func writeInt(buf *bytes.Buffer, intVal int64){
tempBuf := make([]byte, 8)
binary.BigEndian.PutUint64(tempBuf, uint64(intVal))
buf.Write(tempBuf)
func writeInt(buf *bytes.Buffer, intVal int64) {
tempBuf := make([]byte, 8)
binary.BigEndian.PutUint64(tempBuf, uint64(intVal))
buf.Write(tempBuf)
}

func appendChecksum(data []byte) []byte {
checksum := crc64.Checksum(data, crc64.MakeTable(crc64.ECMA))
checksumBuf := make([]byte, 8)
binary.BigEndian.PutUint64(checksumBuf, checksum)
return append(data, checksumBuf...)
checksum := crc64.Checksum(data, crc64.MakeTable(crc64.ECMA))
checksumBuf := make([]byte, 8)
binary.BigEndian.PutUint64(checksumBuf, checksum)
return append(data, checksumBuf...)
}
2 changes: 1 addition & 1 deletion internal/eval/eval.go
Original file line number Diff line number Diff line change
Expand Up @@ -3174,7 +3174,7 @@ func evalHGET(args []string, store *dstore.Store) []byte {
// evalHMGET returns an array of values associated with the given fields,
// in the same order as they are requested.
// If a field does not exist, returns a corresponding nil value in the array.
// If the key does not exist, returns an array of nil values.
// If the key does not exist, returns an array of nil values.
func evalHMGET(args []string, store *dstore.Store) []byte {
if len(args) < 2 {
return diceerrors.NewErrArity("HMGET")
Expand Down
2 changes: 1 addition & 1 deletion internal/server/utils/redisCmdAdapter.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ func ParseHTTPRequest(r *http.Request) (*cmd.DiceDBCmd, error) {

var args []string

//Handle subcommand and multiple arguments
// Handle subcommand and multiple arguments
if subcommand != "" {
args = append(args, subcommand)
}
Expand Down
Loading
Loading