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 }