Spaces:
Sleeping
Sleeping
Scott Hiett commited on
Commit ·
1b2415c
1
Parent(s): bb41a4c
Improve handling for multi exec commands when unable to connect to the Redis server
Browse files
lib/srh/http/command_handler.ex
CHANGED
|
@@ -95,26 +95,35 @@ defmodule Srh.Http.CommandHandler do
|
|
| 95 |
# Borrow a client, then run all of the commands (wrapped in MULTI and EXEC)
|
| 96 |
worker_pid = Client.borrow_worker(client_pid)
|
| 97 |
|
| 98 |
-
|
| 99 |
-
|
| 100 |
-
|
| 101 |
-
|
| 102 |
-
|
| 103 |
-
|
| 104 |
-
|
| 105 |
-
|
| 106 |
-
|
| 107 |
-
|
| 108 |
-
|
| 109 |
-
|
| 110 |
-
|
| 111 |
-
|
| 112 |
-
|
| 113 |
-
|
| 114 |
-
|
| 115 |
-
|
| 116 |
-
|
| 117 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 118 |
|
| 119 |
{:error, msg} ->
|
| 120 |
{:server_error, msg}
|
|
|
|
| 95 |
# Borrow a client, then run all of the commands (wrapped in MULTI and EXEC)
|
| 96 |
worker_pid = Client.borrow_worker(client_pid)
|
| 97 |
|
| 98 |
+
# We are manually going to invoke the MULTI, because there might be a connection error to the Redis server.
|
| 99 |
+
# In that case, we don't want the error to be wound up in the array of errors,
|
| 100 |
+
# we instead want to return the error immediately.
|
| 101 |
+
case ClientWorker.redis_command(worker_pid, ["MULTI"]) do
|
| 102 |
+
{:ok, _} ->
|
| 103 |
+
do_dispatch_command_transaction_array(command_array, worker_pid, responses)
|
| 104 |
+
|
| 105 |
+
# Now manually run the EXEC - this is what contains the information to form the response, not the above
|
| 106 |
+
result =
|
| 107 |
+
case ClientWorker.redis_command(worker_pid, ["EXEC"]) do
|
| 108 |
+
{:ok, res} ->
|
| 109 |
+
{
|
| 110 |
+
:ok,
|
| 111 |
+
res
|
| 112 |
+
|> Enum.map(&%{result: &1})
|
| 113 |
+
}
|
| 114 |
+
|
| 115 |
+
{:error, error} ->
|
| 116 |
+
decode_error(error)
|
| 117 |
+
end
|
| 118 |
+
|
| 119 |
+
Client.return_worker(client_pid, worker_pid)
|
| 120 |
+
|
| 121 |
+
# Fire back the result here, because the initial Multi was successful
|
| 122 |
+
result
|
| 123 |
+
|
| 124 |
+
{:error, error} ->
|
| 125 |
+
decode_error(error)
|
| 126 |
+
end
|
| 127 |
|
| 128 |
{:error, msg} ->
|
| 129 |
{:server_error, msg}
|
lib/srh/http/request_validator.ex
CHANGED
|
@@ -34,7 +34,6 @@ defmodule Srh.Http.RequestValidator do
|
|
| 34 |
defp do_validate_encoding_header([first_item | rest]) do
|
| 35 |
case first_item do
|
| 36 |
"base64" -> {:ok, true}
|
| 37 |
-
|
| 38 |
_ -> do_validate_encoding_header(rest)
|
| 39 |
end
|
| 40 |
end
|
|
|
|
| 34 |
defp do_validate_encoding_header([first_item | rest]) do
|
| 35 |
case first_item do
|
| 36 |
"base64" -> {:ok, true}
|
|
|
|
| 37 |
_ -> do_validate_encoding_header(rest)
|
| 38 |
end
|
| 39 |
end
|
lib/srh/http/result_encoder.ex
CHANGED
|
@@ -1,5 +1,4 @@
|
|
| 1 |
defmodule Srh.Http.ResultEncoder do
|
| 2 |
-
|
| 3 |
# Authentication errors don't get encoded, we need to skip over those
|
| 4 |
def encode_response({:not_authorized, message}) do
|
| 5 |
{:not_authorized, message}
|
|
@@ -27,12 +26,16 @@ defmodule Srh.Http.ResultEncoder do
|
|
| 27 |
## RESULT LIST ENCODING ##
|
| 28 |
|
| 29 |
defp encode_response_list([current | rest], encoded_responses) do
|
| 30 |
-
encoded_current_entry =
|
| 31 |
-
|
| 32 |
-
%{result:
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 36 |
|
| 37 |
encode_response_list(rest, [encoded_current_entry | encoded_responses])
|
| 38 |
end
|
|
|
|
| 1 |
defmodule Srh.Http.ResultEncoder do
|
|
|
|
| 2 |
# Authentication errors don't get encoded, we need to skip over those
|
| 3 |
def encode_response({:not_authorized, message}) do
|
| 4 |
{:not_authorized, message}
|
|
|
|
| 26 |
## RESULT LIST ENCODING ##
|
| 27 |
|
| 28 |
defp encode_response_list([current | rest], encoded_responses) do
|
| 29 |
+
encoded_current_entry =
|
| 30 |
+
case current do
|
| 31 |
+
%{result: value} ->
|
| 32 |
+
# Encode the value
|
| 33 |
+
%{result: encode_result_value(value)}
|
| 34 |
+
|
| 35 |
+
%{error: error_message} ->
|
| 36 |
+
# We don't encode errors
|
| 37 |
+
%{error: error_message}
|
| 38 |
+
end
|
| 39 |
|
| 40 |
encode_response_list(rest, [encoded_current_entry | encoded_responses])
|
| 41 |
end
|
lib/srh/redis/client_registry.ex
CHANGED
|
@@ -48,10 +48,9 @@ defmodule Srh.Redis.ClientRegistry do
|
|
| 48 |
{:ok, pid},
|
| 49 |
%{
|
| 50 |
state_update
|
| 51 |
-
|
| 52 |
-
|
| 53 |
-
|
| 54 |
-
|> Enum.uniq()
|
| 55 |
}
|
| 56 |
}
|
| 57 |
end
|
|
@@ -73,10 +72,9 @@ defmodule Srh.Redis.ClientRegistry do
|
|
| 73 |
:noreply,
|
| 74 |
%{
|
| 75 |
state
|
| 76 |
-
|
| 77 |
-
|
| 78 |
-
|
| 79 |
-
|> Enum.uniq()
|
| 80 |
}
|
| 81 |
}
|
| 82 |
end
|
|
|
|
| 48 |
{:ok, pid},
|
| 49 |
%{
|
| 50 |
state_update
|
| 51 |
+
| currently_borrowed_pids:
|
| 52 |
+
[pid | state_update.currently_borrowed_pids]
|
| 53 |
+
|> Enum.uniq()
|
|
|
|
| 54 |
}
|
| 55 |
}
|
| 56 |
end
|
|
|
|
| 72 |
:noreply,
|
| 73 |
%{
|
| 74 |
state
|
| 75 |
+
| worker_pids:
|
| 76 |
+
[pid | state.worker_pids]
|
| 77 |
+
|> Enum.uniq()
|
|
|
|
| 78 |
}
|
| 79 |
}
|
| 80 |
end
|