aboutsummaryrefslogtreecommitdiff
path: root/pkg/commands/exec.go
diff options
context:
space:
mode:
authoralex <[email protected]>2026-07-12 15:00:16 +0200
committeralex <[email protected]>2026-07-12 15:00:16 +0200
commit6cb3313793bf45e197b3048f0abd2f600bf97bb5 (patch)
tree019a0995c7f9422ec9d739c77379ee7cc1a96b9c /pkg/commands/exec.go
parentce9d9f8b2183bc0a31bfa40e780ae07182bc7cf8 (diff)
downloadredis-clone-6cb3313793bf45e197b3048f0abd2f600bf97bb5.tar.xz
redis-clone-6cb3313793bf45e197b3048f0abd2f600bf97bb5.zip
multi exec and discardmulti/execute
Diffstat (limited to 'pkg/commands/exec.go')
-rw-r--r--pkg/commands/exec.go68
1 files changed, 68 insertions, 0 deletions
diff --git a/pkg/commands/exec.go b/pkg/commands/exec.go
new file mode 100644
index 0000000..a260f69
--- /dev/null
+++ b/pkg/commands/exec.go
@@ -0,0 +1,68 @@
+package commands
+
+import (
+ "errors"
+ "net"
+ "redisClone/pkg/core"
+ "sort"
+)
+
+func Exec(db core.RedisDB, session *ClientSession, conn net.Conn, execArgs []string) interface{} {
+ if session.Queue == nil {
+ return errors.New("EXEC without MULTI")
+ }
+
+ shardMap := make(map[int]*core.Shard)
+ lockedAll := false
+ var sortedIDs []int
+
+ for _, cmdArgs := range session.Queue {
+ cmdName := cmdArgs[0]
+ if cmd, ok := BaseRegistry[cmdName]; ok {
+ if cmd.LocksAll {
+ db.LockAll()
+ lockedAll = true
+ break
+ }
+ for _, key := range cmd.ExtractKeys(cmdArgs) {
+ shard := db.GetShard(key)
+ shardMap[shard.Id] = shard
+ }
+ }
+ }
+
+ if !lockedAll {
+ for id := range shardMap {
+ sortedIDs = append(sortedIDs, id)
+ }
+ sort.Ints(sortedIDs)
+ for _, id := range sortedIDs {
+ shardMap[id].Mu.Lock()
+ }
+
+ defer func() {
+ for i := len(sortedIDs) - 1; i >= 0; i-- {
+ shardMap[sortedIDs[i]].Mu.Unlock()
+ }
+ }()
+ } else {
+ defer db.UnlockAll()
+ }
+
+ var results []interface{}
+
+ for _, cmdArgs := range session.Queue {
+ cmdName := cmdArgs[0]
+ if cmd, ok := BaseRegistry[cmdName]; ok {
+ // Capture the result of the command
+ res := cmd.Execute(cmdArgs, db.GetShard)
+ results = append(results, res)
+ } else {
+ results = append(results, "ERR unknown command")
+ }
+ }
+
+ session.Queue = nil
+
+ return results
+} \ No newline at end of file