Skip to content

Commit 41ff506

Browse files
committed
decode resp and process command
1 parent d0d6181 commit 41ff506

File tree

3 files changed

+42
-8
lines changed

3 files changed

+42
-8
lines changed

lib/command.ex

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
defmodule Redex.Command do
2+
@crlf "\r\n"
3+
@invalid_command_message "Command invalid or not implemented"
4+
5+
6+
def execute([command | _args]) do
7+
case command |> String.upcase do
8+
"COMMAND" -> "+OK" <> @crlf
9+
"PING" -> "+PONG" <> @crlf
10+
_ -> raise @invalid_command_message
11+
end
12+
end
13+
end
14+

lib/redex_server.ex

+23-8
Original file line numberDiff line numberDiff line change
@@ -35,19 +35,34 @@ defmodule Redex.Server do
3535
defp loop_acceptor(socket) do
3636
{:ok, client} = :gen_tcp.accept(socket)
3737
Logger.debug "new client"
38+
39+
# TODO: should use a supervisor here
3840
Task.start(fn -> handle_client(client) end)
3941
loop_acceptor(socket)
4042
end
4143

42-
defp handle_client(socket) do
43-
case socket |> read_line() do
44+
defp close_connection(socket, reason) do
45+
:gen_tcp.close(socket)
46+
Logger.debug "connection closed: #{reason}"
47+
end
48+
49+
defp handle_client(socket, resume \\ nil) do
50+
case socket |> read_line() do
4451
{:ok, line} ->
45-
IO.inspect line
46-
write_line("+PONG\r\n", socket)
47-
handle_client(socket)
48-
{:error, error} ->
49-
:gen_tcp.close(socket)
50-
Logger.debug "connection closed: #{error}"
52+
try do
53+
line = String.trim(line)
54+
result = if resume == nil do Redex.RESPDecoder.read(line) else resume.(line) end
55+
56+
if is_function(result) do
57+
handle_client(socket, result)
58+
else
59+
result |> Redex.Command.execute |> write_line(socket)
60+
handle_client(socket)
61+
end
62+
rescue
63+
e in RuntimeError -> close_connection(socket, e.message)
64+
end
65+
{:error, error} -> close_connection(socket, error)
5166
end
5267
end
5368

test/redex_test.exs

+5
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,9 @@ defmodule RedexServerTest do
3838
{:ok, conn2} = get_connection()
3939
assert Redix.command!(conn2, ["PING"]) == "PONG"
4040
end
41+
42+
test "it can handle mutiple commands from same client", %{conn: conn} do
43+
assert Redix.command!(conn, ["PING"]) == "PONG"
44+
assert Redix.command!(conn, ["PING"]) == "PONG"
45+
end
4146
end

0 commit comments

Comments
 (0)