aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoralex <[email protected]>2026-07-10 18:25:38 +0200
committeralex <[email protected]>2026-07-10 18:25:38 +0200
commitf6d82fac6f2f365e73254993782c490a6995fec3 (patch)
tree77c37f77edd9ec7246961d4583842b3779aea91b
parent8f6257e55c2cb8f4c82fe51fbeaa4a8f66dc30ac (diff)
downloadredis-clone-pubsub.tar.xz
redis-clone-pubsub.zip
refactored handler funcs to have return values instead of writing to conn and to not take conn as a parameterpubsub
-rw-r--r--handlers.go184
-rw-r--r--main.go13
2 files changed, 84 insertions, 113 deletions
diff --git a/handlers.go b/handlers.go
index b5987e8..f3ddf25 100644
--- a/handlers.go
+++ b/handlers.go
@@ -9,11 +9,10 @@ import (
"time"
)
-func handleGet(conn net.Conn, args []string) {
+func handleGet(args []string)interface{} {
if len(args) != 2 {
err := errors.New("wrong number of arguments for 'GET'")
- conn.Write(serializeRESP(err))
- return
+ return err
}
key := args[1]
@@ -37,15 +36,13 @@ func handleGet(conn net.Conn, args []string) {
return strValue
})
-
- conn.Write(serializeRESP(result))
+ return result
}
-func handleExists(conn net.Conn, args []string) {
+func handleExists(args []string)interface{} {
if len(args) != 2 {
err := errors.New("wrong number of arguments for 'EXISTS'")
- conn.Write(serializeRESP(err))
- return
+ return err
}
key := args[1]
@@ -58,14 +55,13 @@ func handleExists(conn net.Conn, args []string) {
}
})
- conn.Write(serializeRESP(result))
+ return result
}
-func handleSet(conn net.Conn, args []string) {
+func handleSet(args []string)interface{} {
if len(args) != 3 {
err := errors.New("wrong number of arguments for 'SET'")
- conn.Write(serializeRESP(err))
- return
+ return err
}
key := args[1]
@@ -75,15 +71,14 @@ func handleSet(conn net.Conn, args []string) {
return SimpleString("OK")
})
- conn.Write(serializeRESP(result))
+ return result
}
-func handleDel(conn net.Conn, args []string) {
+func handleDel(args []string)interface{} {
if len(args) < 2 {
err := errors.New("wrong number of arguments for 'DEL'")
- conn.Write(serializeRESP(err))
- return
+ return err
}
keys := args[1:]
deletedKeys := db.ExecuteMulti(keys, func(shards []*Shard) interface{}{
@@ -98,16 +93,16 @@ func handleDel(conn net.Conn, args []string) {
}
return count
})
- conn.Write(serializeRESP(deletedKeys))
+
+ return deletedKeys
}
-func handleIncr(conn net.Conn, args []string) {
+func handleIncr(args []string)interface{} {
if len(args) != 2 {
err := errors.New("wrong number of arguments for 'INCR'")
- conn.Write(serializeRESP(err))
- return
+ return err
}
key := args[1]
@@ -136,15 +131,14 @@ func handleIncr(conn net.Conn, args []string) {
})
- conn.Write(serializeRESP(result))
+ return result
}
-func handleDecr(conn net.Conn, args []string) {
+func handleDecr(args []string)interface{} {
if len(args) != 2 {
err := errors.New("wrong number of arguments for 'DECR'")
- conn.Write(serializeRESP(err))
- return
+ return err
}
key := args[1]
@@ -172,24 +166,17 @@ func handleDecr(conn net.Conn, args []string) {
}
})
-
- conn.Write(serializeRESP(result))
+ return result
}
func handlePing(conn net.Conn, args []string) {
- if len(args) != 1 {
- err := errors.New("wrong number of arguments for 'PING'")
- conn.Write(serializeRESP(err))
- return
- }
- conn.Write(serializeRESP(SimpleString("PONG")))
+ conn.Write(serializeRESP(SimpleString("OK")))
}
-func handleFlushall(conn net.Conn, args []string) {
+func handleFlushall(args []string)interface{} {
if len(args) != 1 {
err := errors.New("wrong number of arguments for 'FLUSHALL'")
- conn.Write(serializeRESP(err))
- return
+ return err
}
result := db.ExecuteAll(func(shards []*Shard)interface{}{
for _, shard := range shards{
@@ -197,14 +184,13 @@ func handleFlushall(conn net.Conn, args []string) {
}
return SimpleString("OK")
})
- conn.Write(serializeRESP(result))
+ return result
}
-func handleRename(conn net.Conn, args []string){
+func handleRename(args []string)interface{}{
if len(args) != 3 {
err := errors.New("wrong number of arguments for 'RENAME'")
- conn.Write(serializeRESP(err))
- return
+ return err
}
keys := args[1:]
@@ -220,14 +206,13 @@ func handleRename(conn net.Conn, args []string){
return SimpleString("OK")
})
- conn.Write(serializeRESP(result))
+ return result
}
-func handleRpush(conn net.Conn, args []string) {
+func handleRpush(args []string)interface{} {
if len(args) < 3 {
err := errors.New("wrong number of arguments for 'RPUSH'")
- conn.Write(serializeRESP(err))
- return
+ return err
}
key := args[1]
newItems := args[2:]
@@ -248,14 +233,13 @@ func handleRpush(conn net.Conn, args []string) {
s.data[key] = Item{Value: list}
return len(list)
})
- conn.Write(serializeRESP(result))
+ return result
}
-func handleLpush(conn net.Conn, args []string) {
+func handleLpush(args []string)interface{} {
if len(args) < 3 {
err := errors.New("wrong number of arguments for 'LPUSH'")
- conn.Write(serializeRESP(err))
- return
+ return err
}
key := args[1]
newItems := args[2:]
@@ -276,21 +260,20 @@ func handleLpush(conn net.Conn, args []string) {
s.data[key] = Item{Value: list}
return len(list)
})
- conn.Write(serializeRESP(result))
+
+ return result
}
-func handleLrange(conn net.Conn, args []string) {
+func handleLrange(args []string)interface{} {
if len(args) != 4 {
err := errors.New("wrong number of arguments for 'LRANGE'")
- conn.Write(serializeRESP(err))
- return
+ return err
}
start, err1 := strconv.Atoi(args[2])
stop, err2 := strconv.Atoi(args[3])
if err1 != nil || err2 != nil {
err := errors.New("value is not an integer or out of range")
- conn.Write(serializeRESP(err))
- return
+ return err
}
key := args[1]
@@ -328,14 +311,13 @@ func handleLrange(conn net.Conn, args []string) {
}
return typedList[start : stop+1]
})
- conn.Write(serializeRESP(result))
+ return result
}
-func handleLpop(conn net.Conn, args []string) {
+func handleLpop(args []string)interface{} {
if len(args) != 2 {
err := errors.New("wrong number of arguments for 'LPOP'")
- conn.Write(serializeRESP(err))
- return
+ return err
}
key := args[1]
@@ -360,14 +342,13 @@ func handleLpop(conn net.Conn, args []string) {
}
return newItem
})
- conn.Write(serializeRESP(result))
+ return result
}
-func handleRpop(conn net.Conn, args []string) {
+func handleRpop(args []string)interface{} {
if len(args) != 2 {
err := errors.New("wrong number of arguments for 'RPOP'")
- conn.Write(serializeRESP(err))
- return
+ return err
}
key := args[1]
@@ -392,19 +373,17 @@ func handleRpop(conn net.Conn, args []string) {
}
return newItem
})
- conn.Write(serializeRESP(result))
+ return result
}
-func handleExpire(conn net.Conn, args []string) {
+func handleExpire(args []string)interface{} {
if len(args) != 3 {
- conn.Write(serializeRESP(errors.New("wrong number of arguments for 'EXPIRE'")))
- return
+ return errors.New("wrong number of arguments for 'EXPIRE'")
}
key := args[1]
seconds, err := strconv.Atoi(args[2])
if err != nil {
- conn.Write(serializeRESP(errors.New("value is not an integer")))
- return
+ return errors.New("value is not an integer")
}
result := db.Execute(key, func(s *Shard) interface{} {
@@ -417,14 +396,13 @@ func handleExpire(conn net.Conn, args []string) {
s.data[key] = item
return 1
})
- conn.Write(serializeRESP(result))
+ return result
}
-func handleHset(conn net.Conn, args []string) {
+func handleHset(args []string)interface{}{
if len(args) < 4 || (len(args)-2)%2 != 0 {
err := errors.New("wrong number of arguments for 'HSET'")
- conn.Write(serializeRESP(err))
- return
+ return err
}
key := args[1]
@@ -448,13 +426,12 @@ func handleHset(conn net.Conn, args []string) {
s.data[key] = Item{Value: hash}
return count
})
- conn.Write(serializeRESP(result))
+ return result
}
-func handleHget(conn net.Conn, args []string) {
+func handleHget(args []string)interface{} {
if len(args) != 3 {
- conn.Write(serializeRESP(errors.New("wrong number of arguments for 'HGET'")))
- return
+ return errors.New("wrong number of arguments for 'HGET'")
}
key := args[1]
field := args[2]
@@ -474,13 +451,12 @@ func handleHget(conn net.Conn, args []string) {
}
return val
})
- conn.Write(serializeRESP(result))
+ return result
}
-func handleHgetall(conn net.Conn, args []string) {
+func handleHgetall(args []string)interface{} {
if len(args) != 2 {
- conn.Write(serializeRESP(errors.New("wrong number of arguments for 'HGETALL'")))
- return
+ return errors.New("wrong number of arguments for 'HGETALL'")
}
key := args[1]
@@ -495,13 +471,12 @@ func handleHgetall(conn net.Conn, args []string) {
}
return hash
})
- conn.Write(serializeRESP(result))
+ return result
}
-func handleHkeys(conn net.Conn, args []string) {
+func handleHkeys(args []string)interface{} {
if len(args) != 2 {
- conn.Write(serializeRESP(errors.New("wrong number of arguments for 'HKEYS'")))
- return
+ return errors.New("wrong number of arguments for 'HKEYS'")
}
key := args[1]
@@ -520,13 +495,12 @@ func handleHkeys(conn net.Conn, args []string) {
}
return keys
})
- conn.Write(serializeRESP(result))
+ return result
}
-func handleHvalues(conn net.Conn, args []string) {
+func handleHvalues(args []string)interface{} {
if len(args) != 2 {
- conn.Write(serializeRESP(errors.New("wrong number of arguments for 'HVALUES'")))
- return
+ return errors.New("wrong number of arguments for 'HVALUES'")
}
key := args[1]
@@ -545,13 +519,12 @@ func handleHvalues(conn net.Conn, args []string) {
}
return values
})
- conn.Write(serializeRESP(result))
+ return result
}
-func handleType(conn net.Conn, args []string) {
+func handleType(args []string)interface{} {
if len(args) != 2 {
- conn.Write(serializeRESP(errors.New("wrong number of arguments for 'TYPE'")))
- return
+ return errors.New("wrong number of arguments for 'TYPE'")
}
key := args[1]
@@ -571,13 +544,12 @@ func handleType(conn net.Conn, args []string) {
return SimpleString("unknown")
}
})
- conn.Write(serializeRESP(result))
+ return result
}
-func handleDbsize(conn net.Conn, args []string) {
+func handleDbsize(args []string)interface{} {
if len(args) != 1 {
- conn.Write(serializeRESP(errors.New("wrong number of arguments for 'DBSIZE'")))
- return
+ return errors.New("wrong number of arguments for 'DBSIZE'")
}
result := db.ExecuteReadAll(func(shards []*Shard) interface{} {
count := 0
@@ -586,21 +558,19 @@ func handleDbsize(conn net.Conn, args []string) {
}
return count
})
- conn.Write(serializeRESP(result))
+ return result
}
-func handleKeys(conn net.Conn, args []string) {
+func handleKeys(args []string)interface{} {
if len(args) < 2 || len(args) > 3 {
- conn.Write(serializeRESP(errors.New("wrong number of arguments for 'KEYS'")))
- return
+ return errors.New("wrong number of arguments for 'KEYS'")
}
pattern := args[1]
limit := -1
if len(args) == 3 {
val, err := strconv.Atoi(args[2])
if err != nil {
- conn.Write(serializeRESP(errors.New("value is not an integer")))
- return
+ return errors.New("value is not an integer")
}
limit = val
}
@@ -624,20 +594,18 @@ func handleKeys(conn net.Conn, args []string) {
}
return matches
})
- conn.Write(serializeRESP(result))
+ return result
}
-func handleLrem(conn net.Conn, args []string) {
+func handleLrem(args []string)interface{} {
if len(args) != 4 {
- conn.Write(serializeRESP(errors.New("wrong number of arguments for 'LREM'")))
- return
+ return errors.New("wrong number of arguments for 'LREM'")
}
key := args[1]
count, err := strconv.Atoi(args[2])
toBeRemoved := args[3]
if err != nil {
- conn.Write(serializeRESP(errors.New("value is not an integer")))
- return
+ return errors.New("value is not an integer")
}
result := db.Execute(key, func(s *Shard) interface{} {
@@ -699,5 +667,5 @@ func handleLrem(conn net.Conn, args []string) {
}
return counter
})
- conn.Write(serializeRESP(result))
+ return result
} \ No newline at end of file
diff --git a/main.go b/main.go
index 80b78cb..570b512 100644
--- a/main.go
+++ b/main.go
@@ -15,16 +15,16 @@ const NumShards = 16
var db RedisDB
var hub Hub
-type handlerFunc func(net.Conn, []string)
+type baseHandlerFunc func([]string)interface{}
+type connectionHandlerFunc func(net.Conn, []string)
-var commandRegistry = map[string]handlerFunc{
+var baseCommandRegistry = map[string]baseHandlerFunc{
"GET": handleGet,
"SET": handleSet,
"DEL": handleDel,
"EXISTS": handleExists,
"INCR": handleIncr,
"DECR": handleDecr,
- "PING": handlePing,
"RENAME": handleRename,
"FLUSHALL": handleFlushall,
"RPUSH": handleRpush,
@@ -42,9 +42,12 @@ var commandRegistry = map[string]handlerFunc{
"DBSIZE": handleDbsize,
"KEYS": handleKeys,
"LREM": handleLrem,
+}
+var connectionCommandRegistry = map[string]connectionHandlerFunc{
"SUBSCRIBE": handleSubscribe,
"UNSUBSCRIBE": handleUnsubscribe,
"PUBLISH": handlePublish,
+ "PING": handlePing,
}
func main() {
@@ -115,8 +118,8 @@ func handleConnection(conn net.Conn) {
command := strings.ToUpper(args[0])
- if handler, ok := commandRegistry[command]; ok {
- handler(conn, args)
+ if handler, ok := baseCommandRegistry[command]; ok {
+ conn.Write(serializeRESP(handler(args)))
} else {
conn.Write(serializeRESP(errors.New("unknown command")))
}