Codebase list erlang-redis-client / 6551e02
Import upstream version 1.2.0+git20190128.1.6845ed5 Debian Janitor 2 years ago
11 changed file(s) with 84 addition(s) and 36 deletion(s). Raw diff Collapse all Expand all
0 ebin/*
1 .eunit
2 *~
3 Emakefile
4 .rebar
5 .DS_Store
6 doc
7 _build
8 erl_crash.dump
0 language: erlang
1 sudo: required
2 notifications:
3 email: false
4 otp_release:
5 - 21.0.1
6 - 20.3
7 - 19.3
8 - 19.2
9 - 19.1
10 - 19.0
11 - 18.3
12 - 18.2.1
13 - 18.1
14 - 17.5
15 - 17.4
16 - 17.3
17 - 17.1
18 - 17.0
19 - R16B03-1
20 - R16B03
21 - R16B02
22 - R16B01
23 services:
24 - redis-server
113113 where the values are the redis responses in the same order as the
114114 commands you provided.
115115
116 To start the client, use any of the `eredis:start_link/0,1,2,3,4,5`
117 functions. They all include sensible defaults. `start_link/5` takes
116 To start the client, use any of the `eredis:start_link/0,1,2,3,4,5,6,7`
117 functions. They all include sensible defaults. `start_link/7` takes
118118 the following arguments:
119119
120120 * Host, dns name or ip adress as string; or unix domain socket as {local, Path} (available in OTP 19+)
122122 * Database, integer or 0 for default database
123123 * Password, string or empty string([]) for no password
124124 * Reconnect sleep, integer of milliseconds to sleep between reconnect attempts
125 * Connect timeout, timeout value in milliseconds to use in `gen_tcp:connect`, default is 5000
126 * Socket options, proplist of options to be sent to `gen_tcp:connect`, default is `?SOCKET_OPTS`
125127
126128 ## Reconnecting on Redis down / network failure / timeout / etc
127129
3232
3333 -define(NL, "\r\n").
3434
35 -define(SOCKET_OPTS, [binary, {active, once}, {packet, raw}, {reuseaddr, false},
36 {send_timeout, ?SEND_TIMEOUT}]).
35 -define(SOCKET_MODE, binary).
36 -define(SOCKET_OPTS, [{active, once}, {packet, raw}, {reuseaddr, false},
37 {keepalive, false}, {send_timeout, ?SEND_TIMEOUT}]).
3738
3839 -define(RECV_TIMEOUT, 5000).
3940 -define(SEND_TIMEOUT, 5000).
33 def project do
44 [
55 app: :eredis,
6 version: "1.1.0",
6 version: "1.2.0",
77 elixir: "~> 1.5.1",
88 start_permanent: Mix.env == :prod,
99 deps: deps()
0 {application, eredis, [
1 {description, "Erlang Redis Client"},
2 {vsn, "1.1.0"},
3 {modules, [eredis, eredis_client, eredis_parser, eredis_sub, eredis_sub_client]},
4 {registered, []},
5 {applications, [kernel, stdlib]},
6 {maintainers, ["Knut Nesheim"]},
7 {licenses, ["MIT"]}
8 ]}.
0 {application,eredis,
1 [{description,"Erlang Redis Client"},
2 {vsn,"1.2.0"},
3 {modules,[eredis,eredis_client,eredis_parser,eredis_sub,
4 eredis_sub_client]},
5 {registered,[]},
6 {applications,[kernel,stdlib]},
7 {maintainers,["Knut Nesheim"]},
8 {licenses,["MIT"]}]}.
1313 -define(TIMEOUT, 5000).
1414
1515 -export([start_link/0, start_link/1, start_link/2, start_link/3, start_link/4,
16 start_link/5, start_link/6, stop/1, q/2, q/3, qp/2, qp/3, q_noreply/2,
16 start_link/5, start_link/6, start_link/7, stop/1, q/2, q/3, qp/2, qp/3, q_noreply/2,
1717 q_async/2, q_async/3]).
1818
1919 %% Exported for testing
4545 start_link(Host, Port, Database, Password, ReconnectSleep) ->
4646 start_link(Host, Port, Database, Password, ReconnectSleep, ?TIMEOUT).
4747
48 start_link(Host, Port, Database, Password, ReconnectSleep, ConnectTimeout)
48 start_link(Host, Port, Database, Password, ReconnectSleep, ConnectTimeout) ->
49 start_link(Host, Port, Database, Password, ReconnectSleep, ConnectTimeout, []).
50
51 start_link(Host, Port, Database, Password, ReconnectSleep, ConnectTimeout, SocketOptions)
4952 when is_list(Host) orelse
5053 (is_tuple(Host) andalso tuple_size(Host) =:= 2 andalso element(1, Host) =:= local),
5154 is_integer(Port),
5255 is_integer(Database) orelse Database == undefined,
5356 is_list(Password),
5457 is_integer(ReconnectSleep) orelse ReconnectSleep =:= no_reconnect,
55 is_integer(ConnectTimeout) ->
58 is_integer(ConnectTimeout),
59 is_list(SocketOptions) ->
5660
5761 eredis_client:start_link(Host, Port, Database, Password,
58 ReconnectSleep, ConnectTimeout).
62 ReconnectSleep, ConnectTimeout, SocketOptions).
5963
6064 %% @doc: Callback for starting from poolboy
6165 -spec start_link(server_args()) -> {ok, Pid::pid()} | {error, Reason::term()}.
6670 Password = proplists:get_value(password, Args, ""),
6771 ReconnectSleep = proplists:get_value(reconnect_sleep, Args, 100),
6872 ConnectTimeout = proplists:get_value(connect_timeout, Args, ?TIMEOUT),
69 start_link(Host, Port, Database, Password, ReconnectSleep, ConnectTimeout).
73 SocketOptions = proplists:get_value(socket_options, Args, []),
74
75 start_link(Host, Port, Database, Password, ReconnectSleep, ConnectTimeout, SocketOptions).
7076
7177 stop(Client) ->
7278 eredis_client:stop(Client).
2424 -include("eredis.hrl").
2525
2626 %% API
27 -export([start_link/6, stop/1, select_database/2]).
27 -export([start_link/7, stop/1, select_database/2]).
2828
2929 -export([do_sync_command/2]).
3030
3939 database :: binary() | undefined,
4040 reconnect_sleep :: reconnect_sleep() | undefined,
4141 connect_timeout :: integer() | undefined,
42 socket_options :: list(),
4243
4344 socket :: port() | undefined,
4445 parser_state :: #pstate{} | undefined,
5455 Database::integer() | undefined,
5556 Password::string(),
5657 ReconnectSleep::reconnect_sleep(),
57 ConnectTimeout::integer() | undefined) ->
58 ConnectTimeout::integer() | undefined,
59 SocketOptions::list()) ->
5860 {ok, Pid::pid()} | {error, Reason::term()}.
59 start_link(Host, Port, Database, Password, ReconnectSleep, ConnectTimeout) ->
61 start_link(Host, Port, Database, Password, ReconnectSleep, ConnectTimeout, SocketOptions) ->
6062 gen_server:start_link(?MODULE, [Host, Port, Database, Password,
61 ReconnectSleep, ConnectTimeout], []).
63 ReconnectSleep, ConnectTimeout, SocketOptions], []).
6264
6365
6466 stop(Pid) ->
6870 %% gen_server callbacks
6971 %%====================================================================
7072
71 init([Host, Port, Database, Password, ReconnectSleep, ConnectTimeout]) ->
73 init([Host, Port, Database, Password, ReconnectSleep, ConnectTimeout, SocketOptions]) ->
7274 State = #state{host = Host,
7375 port = Port,
7476 database = read_database(Database),
7577 password = list_to_binary(Password),
7678 reconnect_sleep = ReconnectSleep,
7779 connect_timeout = ConnectTimeout,
80 socket_options = SocketOptions,
7881
7982 parser_state = eredis_parser:init(),
8083 queue = queue:new()},
305308 local -> 0;
306309 _ -> State#state.port
307310 end,
308 case gen_tcp:connect(Addr, Port,
309 [AFamily | ?SOCKET_OPTS], State#state.connect_timeout) of
311
312 SocketOptions = lists:ukeymerge(1, lists:keysort(1, State#state.socket_options), lists:keysort(1, ?SOCKET_OPTS)),
313 ConnectOptions = [AFamily | [?SOCKET_MODE | SocketOptions]],
314
315 case gen_tcp:connect(Addr, Port, ConnectOptions, State#state.connect_timeout) of
310316 {ok, Socket} ->
311317 case authenticate(Socket, State#state.password) of
312318 ok ->
309309 %% synchronous and if Redis returns something we don't expect, we
310310 %% crash. Returns {ok, State} or {error, Reason}.
311311 connect(State) ->
312 case gen_tcp:connect(State#state.host, State#state.port, ?SOCKET_OPTS) of
312 case gen_tcp:connect(State#state.host, State#state.port, [?SOCKET_MODE | ?SOCKET_OPTS]) of
313313 {ok, Socket} ->
314314 case authenticate(Socket, State#state.password) of
315315 ok ->
2727 eredis_sub:ack_message(Sub)
2828 end
2929 end, Channels).
30
31
32
33
34
3530
3631 pubsub_test() ->
3732 Pub = c(),
77 connect_test() ->
88 ?assertMatch({ok, _}, eredis:start_link("127.0.0.1", 6379)),
99 ?assertMatch({ok, _}, eredis:start_link("localhost", 6379)).
10
11 connect_socket_options_test() ->
12 ?assertMatch({ok, _}, eredis:start_link([{socket_options, [{keepalive, true}]}])),
13 ?assertMatch({ok, _}, eredis:start_link("localhost", 6379, 0, "",100, 5000, [{keepalive, true}])).
1014
1115 get_set_test() ->
1216 C = c(),
155159 process_flag(trap_exit, true),
156160 Res = eredis:start_link("localhost", 6378, 0, "", no_reconnect),
157161 ?assertMatch({error, _}, Res),
158 IsDied = receive {'EXIT', _, _} -> died
162 IsDead = receive {'EXIT', _, _} -> died
159163 after 1000 -> still_alive end,
160164 process_flag(trap_exit, false),
161 ?assertEqual(died, IsDied).
165 ?assertEqual(died, IsDead).
162166
163167 connection_failure_during_start_reconnect_test() ->
164168 process_flag(trap_exit, true),
165169 Res = eredis:start_link("localhost", 6378, 0, "", 100),
166170 ?assertMatch({ok, _}, Res),
167171 {ok, ClientPid} = Res,
168 IsDied = receive {'EXIT', ClientPid, _} -> died
172 IsDead = receive {'EXIT', ClientPid, _} -> died
169173 after 400 -> still_alive end,
170174 process_flag(trap_exit, false),
171 ?assertEqual(still_alive, IsDied).
175 ?assertEqual(still_alive, IsDead).
172176
173177 tcp_closed_test() ->
174178 C = c(),