diff options
| author | alex <[email protected]> | 2026-07-12 15:00:16 +0200 |
|---|---|---|
| committer | alex <[email protected]> | 2026-07-12 15:00:16 +0200 |
| commit | 6cb3313793bf45e197b3048f0abd2f600bf97bb5 (patch) | |
| tree | 019a0995c7f9422ec9d739c77379ee7cc1a96b9c /pkg/commands/exec.go | |
| parent | ce9d9f8b2183bc0a31bfa40e780ae07182bc7cf8 (diff) | |
| download | redis-clone-multi/execute.tar.xz redis-clone-multi/execute.zip | |
multi exec and discardmulti/execute
Diffstat (limited to 'pkg/commands/exec.go')
| -rw-r--r-- | pkg/commands/exec.go | 68 |
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 |
