diff --git a/README.md b/README.md index 696e10e4..5c16a6ea 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,7 @@ Improvements and changes compared to `wooga/eredis`: * Support of TLS introduced in Redis 6 * Changed API: `start_link` takes a proplist with options * Correction regarding chunked error responses +* Correction regarding termination of the reconnect process * Dialyzer corrections * Elvis code formatting * Improved test coverage diff --git a/src/eredis_client.erl b/src/eredis_client.erl index c43167a6..24adc8ca 100644 --- a/src/eredis_client.erl +++ b/src/eredis_client.erl @@ -477,7 +477,9 @@ maybe_reconnect(Reason, #state{queue = Queue} = State) -> error_logger:error_msg("eredis: Re-establishing connection to ~p:~p due to ~p", [State#state.host, State#state.port, Reason]), Self = self(), - spawn_link(fun() -> reconnect_loop(Self, State) end), + spawn_link(fun() -> process_flag(trap_exit, true), + reconnect_loop(Self, State) + end), %% tell all of our clients what has happened. reply_all({error, Reason}, Queue), @@ -491,20 +493,24 @@ maybe_reconnect(Reason, #state{queue = Queue} = State) -> %% successfully issuing the auth and select calls. When we have a %% connection, give the socket to the redis client. reconnect_loop(Client, #state{reconnect_sleep=ReconnectSleep, transport=Transport}=State) -> - timer:sleep(ReconnectSleep), - case catch(connect(State)) of - {ok, #state{socket = Socket}} -> - Client ! {connection_ready, Socket}, - Transport:controlling_process(Socket, Client), - Msgs = get_all_messages([]), - [Client ! M || M <- Msgs]; - {error, _Reason} -> - reconnect_loop(Client, State); - %% Something bad happened when connecting, like Redis might be - %% loading the dataset and we got something other than 'OK' in - %% auth or select - _ -> - reconnect_loop(Client, State) + receive + {'EXIT', Client, Reason} -> exit(Reason) + after + ReconnectSleep -> + case catch(connect(State)) of + {ok, #state{socket = Socket}} -> + Client ! {connection_ready, Socket}, + Transport:controlling_process(Socket, Client), + Msgs = get_all_messages([]), + [Client ! M || M <- Msgs]; + {error, _Reason} -> + reconnect_loop(Client, State); + %% Something bad happened when connecting, like Redis might be + %% loading the dataset and we got something other than 'OK' in + %% auth or select + _ -> + reconnect_loop(Client, State) + end end. read_database(undefined) -> diff --git a/test/eredis_tcp_SUITE.erl b/test/eredis_tcp_SUITE.erl index 426439a6..b8846aed 100644 --- a/test/eredis_tcp_SUITE.erl +++ b/test/eredis_tcp_SUITE.erl @@ -311,9 +311,10 @@ t_reconnect(Config) when is_list(Config) -> {ok, C} = eredis:start_link("127.0.0.1", ?PORT, [{password, "wrong_password"}, {reconnect_sleep, 100}, {connect_timeout, 200}]), - timer:sleep(2000), + timer:sleep(1000), %% expect a couple of reconnect attempts ?assert(length(get_tcp_ports()) =< 1), ?assertMatch(ok, eredis:stop(C)), + timer:sleep(200), %% Wait for reconnect process to terminate ?assertEqual(0, length(get_tcp_ports())). %% diff --git a/test/eredis_tls_SUITE.erl b/test/eredis_tls_SUITE.erl index 694cc743..18c775c3 100644 --- a/test/eredis_tls_SUITE.erl +++ b/test/eredis_tls_SUITE.erl @@ -155,9 +155,10 @@ t_reconnect(Config) when is_list(Config) -> {reconnect_sleep, 100}, {connect_timeout, 200}], C = c_tls(ExtraOptions), - timer:sleep(2000), + timer:sleep(1000), %% expect a couple of reconnect attempts ?assert(length(get_tcp_ports()) =< 1), ?assertMatch(ok, eredis:stop(C)), + timer:sleep(200), %% Wait for reconnect process to terminate ?assertEqual(0, length(get_tcp_ports())). %%