// Dispatch takes in a client whose command has already been read off the // socket, a list of arguments from that command (not including the command name // itself), and handles that command func Dispatch(client *clients.Client, cmd string, args []string) { cmdInfo, ok := commandMap[strings.ToUpper(cmd)] if !ok { writeErrf(client.Conn, "ERR unknown command %q", cmd) return } if len(args) < cmdInfo.minArgs { writeErrf(client.Conn, "ERR missing args") return } ret, err := cmdInfo.f(client, args) if err != nil { writeErrf(client.Conn, "ERR unexpected server-side error") log.L.Print(client.Sprintf("command %s %#v err: %s", cmd, args, err)) return } redis.NewResp(ret).WriteTo(client.Conn) }
func serveClient(client *clients.Client) { conn := client.Conn rr := redis.NewRespReader(conn) outer: for { var command string var args []string m := rr.Read() if m.IsType(redis.IOErr) { log.L.Debug(client.Sprintf("client connection error %q", m.Err)) if len(client.Queues) > 0 { consumers.UpdateQueues(client, []string{}) } client.Close() return } parts, err := m.Array() if err != nil { log.L.Debug(client.Sprintf("error parsing to array: %q", err)) continue outer } for i := range parts { val, err := parts[i].Str() if err != nil { log.L.Debug(client.Sprintf("invalid command part %#v: %s", parts[i], err)) invalidCmdResp.WriteTo(conn) continue outer } if i == 0 { command = val } else { args = append(args, val) } } log.L.Debug(client.Sprintf("%s %#v", command, args)) commands.Dispatch(client, command, args) } }