diff options
| author | alex <[email protected]> | 2026-07-12 14:09:36 +0200 |
|---|---|---|
| committer | alex <[email protected]> | 2026-07-12 14:09:36 +0200 |
| commit | ce9d9f8b2183bc0a31bfa40e780ae07182bc7cf8 (patch) | |
| tree | 73eefd7228bb3ba820c618777495b60a3fb6860f | |
| parent | 89b3019a3ab77a3e72720342fc0e5bea996fa4f2 (diff) | |
| download | redis-clone-ce9d9f8b2183bc0a31bfa40e780ae07182bc7cf8.tar.xz redis-clone-ce9d9f8b2183bc0a31bfa40e780ae07182bc7cf8.zip | |
added pubsub command registrycommand-registry
| -rw-r--r-- | main.go | 10 | ||||
| -rw-r--r-- | pkg/commands/command-registry.go | 34 | ||||
| -rw-r--r-- | pkg/commands/publish.go | 12 | ||||
| -rw-r--r-- | pkg/commands/subscribe.go | 13 | ||||
| -rw-r--r-- | pkg/commands/unsubscribe.go | 19 |
5 files changed, 79 insertions, 9 deletions
@@ -86,7 +86,13 @@ func handleConnection(conn net.Conn) { command := strings.ToUpper(args[0]) - conn.Write(core.SerializeRESP(commands.DispatchBaseCommand(db,command,args))) - + if cmd , ok := commands.PubSubRegistry[command]; ok { + commands.DispatchPubSub(conn, &hub, cmd, args) + } else if cmd, ok := commands.BaseRegistry[command]; ok { + res := commands.DispatchBaseCommand(db, cmd, args) + conn.Write(core.SerializeRESP(res)) + } else { + conn.Write(core.SerializeRESP(fmt.Errorf("ERR unknown command '%s'", command))) + } } }
\ No newline at end of file diff --git a/pkg/commands/command-registry.go b/pkg/commands/command-registry.go index 068fe7c..19c8acc 100644 --- a/pkg/commands/command-registry.go +++ b/pkg/commands/command-registry.go @@ -2,7 +2,9 @@ package commands import ( "errors" + "net" "redisClone/pkg/core" + "redisClone/pkg/pubsub" ) var dbInstance core.RedisDB @@ -27,17 +29,13 @@ func RenameKeys(args []string) []string { return []string{args[1], args[2]} } -type CommandDef struct{ +type BaseCommand struct{ MinArgs int ExtractKeys func(args []string)[]string Execute func(args []string, getShard func(k string) *core.Shard) interface{} } -func DispatchBaseCommand(db core.RedisDB ,commandName string, args []string) interface{} { - cmd, exists := Registry[commandName] - if !exists { - return nil - } +func DispatchBaseCommand(db core.RedisDB ,cmd BaseCommand, args []string) interface{} { if len(args) < cmd.MinArgs { return errors.New("wrong number of arguments") @@ -50,7 +48,23 @@ func DispatchBaseCommand(db core.RedisDB ,commandName string, args []string) int return cmd.Execute(args, db.GetShard) } -var Registry = map[string]CommandDef{ +type PubSubCommand struct{ + MinArgs int + Execute func(hub *pubsub.Hub, conn net.Conn, args []string) interface{} +} + +func DispatchPubSub(conn net.Conn, h *pubsub.Hub, cmd PubSubCommand, args []string) { + if len(args) < cmd.MinArgs { + conn.Write(core.SerializeRESP(errors.New("ERR wrong number of arguments"))) + return + } + if res := cmd.Execute(h, conn, args); res != nil { + conn.Write(core.SerializeRESP(res)) + } +} + + +var BaseRegistry = map[string]BaseCommand{ "GET": { MinArgs: 2, ExtractKeys: SingleKey, @@ -171,4 +185,10 @@ var Registry = map[string]CommandDef{ ExtractKeys: NoKeys, Execute: Ping, }, +} + +var PubSubRegistry = map[string]PubSubCommand{ + "SUBSCRIBE": {MinArgs: 2, Execute: Subscribe}, + "UNSUBSCRIBE": {MinArgs: 1, Execute: Unsubscribe}, + "PUBLISH": {MinArgs: 3, Execute: Publish}, }
\ No newline at end of file diff --git a/pkg/commands/publish.go b/pkg/commands/publish.go new file mode 100644 index 0000000..5959d57 --- /dev/null +++ b/pkg/commands/publish.go @@ -0,0 +1,12 @@ +package commands + +import ( + "net" + "redisClone/pkg/pubsub" +) + +func Publish(hub *pubsub.Hub, conn net.Conn, args []string) interface{}{ + channel := args[1] + msg := args[2] + return hub.Publish(channel, msg) +}
\ No newline at end of file diff --git a/pkg/commands/subscribe.go b/pkg/commands/subscribe.go new file mode 100644 index 0000000..06dee13 --- /dev/null +++ b/pkg/commands/subscribe.go @@ -0,0 +1,13 @@ +package commands + +import ( + "net" + "redisClone/pkg/pubsub" +) + +func Subscribe(hub *pubsub.Hub, conn net.Conn, args []string) interface{}{ + for _, channel := range args[1:]{ + hub.Subscribe(conn,channel) + } + return nil +}
\ No newline at end of file diff --git a/pkg/commands/unsubscribe.go b/pkg/commands/unsubscribe.go new file mode 100644 index 0000000..9ca502d --- /dev/null +++ b/pkg/commands/unsubscribe.go @@ -0,0 +1,19 @@ +package commands + +import ( + "net" + "redisClone/pkg/core" + "redisClone/pkg/pubsub" +) + +func Unsubscribe(hub *pubsub.Hub, conn net.Conn, args []string) interface{}{ + channels := args[1:] + results := hub.Unsubscribe(conn, channels) + + for channel, remainingCount := range results { + resp := core.SerializeRESP([]interface{}{"unsubscribe", channel, remainingCount}) + conn.Write(resp) + } + + return nil +}
\ No newline at end of file |
