Skip to content

Commit

Permalink
Simplify eetcd:open function with a single options parameter
Browse files Browse the repository at this point in the history
These changes break the original API style, replace it with a simpler style: `eetcd:open(Name, Endopoints, Options)`.
  • Loading branch information
belltoy committed Mar 19, 2023
1 parent f5da989 commit 9c672d2
Show file tree
Hide file tree
Showing 7 changed files with 63 additions and 60 deletions.
17 changes: 11 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -296,17 +296,22 @@ Migration from eetcd 0.3.6 to 0.4.x
eetcd 0.4.x now dependents on Gun 2.0, which introduced some breaking changes,
and propagate to eetcd.

The transport options are split into `tcp_opts` and `tls_opts`. As a result the
functions `eetcd:open/4,5` have been replaced with `eetcd:open/5,6`.
The prior transport options are split into `tcp_opts` and `tls_opts` and moved
inside the new `eetcd:opts()` parameter. As a result, the functions `eetcd:open/4,5`
have been replaced with `eetcd:open/2,3`.

Likewise, the transport options for `eetcd_maintenance` APIs are split into
`tcp_opts` and `tls_opts` as well.

- The function `eetcd_maintenance:defragment/3` has been replaced with `eetcd_maintenance:defragment/4`.
- The function `eetcd_maintenance:status/3` has been replaced with `eetcd_maintenance:status/4`.
- The function `eetcd_maintenance:has_kv/4` has been replaced with `eetcd_maintenance:has_kv/5`.
- The function `eetcd:open/4,5` has been replaced with `eetcd:open/3`.
- The function `eetcd_maintenance:defragment/3` has been replaced with `eetcd_maintenance:defragment/2`.
- The function `eetcd_maintenance:status/3` has been replaced with `eetcd_maintenance:status/2`.
- The function `eetcd_maintenance:has_kv/4` has been replaced with `eetcd_maintenance:has_kv/3`.

New options `{domain_lookup_timeout, Interval}` and `{tls_handshake_timeout, Interval}`
have been added for `eetcd:open/5,6`. Alone with the prior `{connect_timeout, Interval}`,
have been added for `eetcd:open/3`. Alone with the prior `{connect_timeout, Interval}`,
it allows the underlining Gun library to get separate events when connecting,
the domain lookup, connection and TLS handshakes.
- `tls_opts` Passed to Gun.

Read more details of Gun options in the [Gun 2.0 manual](https://ninenines.eu/docs/en/gun/2.0/manual/gun/).
64 changes: 31 additions & 33 deletions src/eetcd.erl
Original file line number Diff line number Diff line change
@@ -1,33 +1,35 @@
-module(eetcd).
-include("eetcd.hrl").
%% API
-export([open/2, open/5, open/6, close/1]).
-export([open/2, open/3, close/1]).
-export([info/0]).
-export([new/1, with_timeout/2]).
-export([get_prefix_range_end/1]).
-export_type([opts/0]).

-type opts() :: [ {mode, connect_all | random} |
{transport, tcp | tls | ssl} |
{name, string()} |
{password, string()} |
{auto_sync_interval_ms, non_neg_integer()} |
{retry, non_neg_integer()} |
{retry_timeout, pos_integer()} |
{connect_timeout, timeout()} |
{domain_lookup_timeout, timeout()} |
{tls_handshake_timeout, timeout()} |
{tcp_opts, [gen_tcp:connect_option()]} |
{tls_opts, [ssl:tls_client_option()]}
].

%% @doc Connects to a etcd server on TCP port
%% Port on the host with IP address Address, such as:
%% `open(test,["127.0.0.1:2379","127.0.0.1:2479","127.0.0.1:2579"]).'
-spec open(name(), [string()]) -> {ok, pid()} | {error, any()}.
open(Name, Hosts) ->
open(Name, Hosts, [], tcp, [], []).

%% @doc Connects to a etcd server.
-spec open(name(),
[string()],
tcp | tls | ssl,
[gen_tcp:connect_option()],
[ssl:tls_client_option()]) ->
{ok, pid()} | {error, any()}.
open(Name, Hosts, Transport, TcpOpts, TlsOpts) when is_atom(Transport) ->
open(Name, Hosts, [], Transport, TcpOpts, TlsOpts).
open(Name, Hosts, [{transport, tcp}]).

%% @doc Connects to a etcd server.
%%
%% @see `ssl:tls_client_option()' see all tls client options in `ssl' module.
%% such as [{certfile, Certfile}, {keyfile, Keyfile}] or [{cert, Cert}, {key, Key}].
%%
%% Default mode is `connect_all', it creates multiple sub-connections (one sub-connection per each endpoint).
%% The balancing policy is round robin.
%% For instance, in 5-node cluster, `connect_all' would require 5 TCP connections,
Expand Down Expand Up @@ -55,26 +57,22 @@ open(Name, Hosts, Transport, TcpOpts, TlsOpts) when is_atom(Transport) ->
%%
%% `[{name, string()}, {password, string()}]' generates an authentication token based on a given user name and password.
%%
%% `{tcp_opts, [gen_tcp:connect_option()]}' and `{tls_opts, [ssl:tls_client_option()]}' are the
%% options for gun:open/3 in Gun 2.0.
%%
%% See all TCP options in {@link gen_tcp} module.
%%
%% See all TLS client options in {@link ssl} module,
%% such as `[{certfile, Certfile}, {keyfile, Keyfile}] or [{cert, Cert}, {key, Key}]'.
%%
%% Read more details of gun options in the
%% [https://ninenines.eu/docs/en/gun/2.0/manual/gun/ Gun 2.0 manual].
%%
%% You can use `eetcd:info/0' to see the internal connection status.
-spec open(name(),
[string()],
[
{mode, connect_all | random}
| {name, string()}
| {password, string()}
| {retry, non_neg_integer()}
| {retry_timeout, pos_integer()}
| {connect_timeout, timeout()}
| {domain_lookup_timeout, timeout()}
| {tls_handshake_timeout, timeout()}
],
tcp | tls | ssl,
[gen_tcp:connect_option()],
[ssl:tls_client_option()]) ->
{ok, pid()} | {error, any()}.
open(Name, Hosts, Options, Transport, TcpOpts, TlsOpts) ->
-spec open(name(), [string()], opts()) -> {ok, pid()} | {error, any()}.
open(Name, Hosts, Options) ->
Cluster = [begin [IP, Port] = string:tokens(Host, ":"), {IP, list_to_integer(Port)} end || Host <- Hosts],
eetcd_conn_sup:start_child([{Name, Cluster, Options, Transport, TcpOpts, TlsOpts}]).
eetcd_conn_sup:start_child([{Name, Cluster, Options}]).

%% @doc close connections with etcd server.
-spec close(name()) -> ok | {error, eetcd_conn_unavailable}.
Expand Down
8 changes: 4 additions & 4 deletions src/eetcd_conn.erl
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ flush_token(Gun, Headers) ->
%%%===================================================================
%%% gen_statem callbacks
%%%===================================================================
init({Name, Hosts, Options, Transport, TcpOpts, TlsOpts}) ->
init({Name, Hosts, Options}) ->
erlang:process_flag(trap_exit, true),
GunOpts = #{protocols => [http2],
connect_timeout => proplists:get_value(connect_timeout, Options, 1000),
Expand All @@ -98,9 +98,9 @@ init({Name, Hosts, Options, Transport, TcpOpts, TlsOpts}) ->
http2_opts => #{keepalive => 45000},
retry => proplists:get_value(retry, Options, 0),
retry_timeout => proplists:get_value(retry_timeout, Options, 5000),
transport => Transport,
tcp_opts => TcpOpts,
tls_opts => TlsOpts
transport => proplists:get_value(transport, Options, tcp),
tcp_opts => proplists:get_value(tcp_opts, Options, []),
tls_opts => proplists:get_value(tls_opts, Options, [])
},
AutoSyncInterval = proplists:get_value(auto_sync_interval_ms, Options, 0),
Data0 = #{
Expand Down
24 changes: 12 additions & 12 deletions src/eetcd_maintenance.erl
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
-include("eetcd.hrl").
%% API
-export([alarm_list/1, alarm_disarm/3, alarm_disarm_all/1]).
-export([defragment/4, status/4, hash_kv/5, move_leader/2]).
-export([defragment/2, status/2, hash_kv/3, move_leader/2]).

%%% @doc AlarmList gets all active alarms.
-spec alarm_list(name()|context()) ->
Expand Down Expand Up @@ -46,30 +46,30 @@ alarm_disarm_all(ConnName) ->
%%% Defragment is an expensive operation. User should avoid defragmenting multiple members at the same time.
%%% To defragment multiple members in the cluster, user need to call defragment multiple
%%% times with different endpoints.
-spec defragment(iodata(), tcp | tls | ssl, [gen_tcp:connect_option()], [ssl:tls_client_option()]) ->
-spec defragment(iodata(), eetcd:opts()) ->
{ok,router_pb:'Etcd.DefragmentResponse'()}|{error,eetcd_error()}.
defragment(Endpoint, Transport, TcpOpts, TlsOpts) ->
defragment(Endpoint, Options) ->
Fun = fun(Conn) -> eetcd_maintenance_gen:defragment(eetcd:new(Conn)) end,
dial(Endpoint, Transport, TcpOpts, TlsOpts, Fun).
dial(Endpoint, Options, Fun).

%%% @doc Status gets the status of the endpoint.
-spec status(iodata(), tcp | tls | ssl, [gen_tcp:connect_option()], [ssl:tls_client_option()]) ->
-spec status(iodata(), eetcd:opts()) ->
{ok,router_pb:'Etcd.StatusResponse'()}|{error,eetcd_error()}.
status(Endpoint, Transport, TcpOpts, TlsOpts) ->
status(Endpoint, Options) ->
Fun = fun(Conn) -> eetcd_maintenance_gen:status(eetcd:new(Conn)) end,
dial(Endpoint, Transport, TcpOpts, TlsOpts, Fun).
dial(Endpoint, Options, Fun).

%%% @doc HashKV returns a hash of the KV state at the time of the RPC.
%%% If revision is zero, the hash is computed on all keys. If the revision
%%% is non-zero, the hash is computed on all keys at or below the given revision.
-spec hash_kv(iodata(), tcp | tls | ssl, [gen_tcp:connect_option()], [ssl:tls_client_option()], pos_integer()) ->
-spec hash_kv(iodata(), eetcd:opts(), pos_integer()) ->
{ok,router_pb:'Etcd.HashKVResponse'()}|{error,eetcd_error()}.
hash_kv(Endpoint, Transport, TcpOpts, TlsOpts, Rev) ->
hash_kv(Endpoint, Options, Rev) ->
Fun = fun(Conn) ->
Context = maps:put(revision, Rev, eetcd:new(Conn)),
eetcd_maintenance_gen:hash_kv(Context)
end,
dial(Endpoint, Transport, TcpOpts, TlsOpts, Fun).
dial(Endpoint, Options, Fun).

%%% Snapshot provides a reader for a point-in-time snapshot of etcd.
%%% If the context "ctx" is canceled or timed out, reading from returned
Expand All @@ -89,10 +89,10 @@ move_leader(Context, TargetID) ->
%%%===================================================================
%%% Internal functions
%%%===================================================================
dial(Endpoint, Transport, TcpOpts, TlsOpts, Fun) ->
dial(Endpoint, Options, Fun) ->
Conn = make_ref(),
try
case eetcd:open(Conn, [Endpoint], Transport, TcpOpts, TlsOpts) of
case eetcd:open(Conn, [Endpoint], Options) of
{ok, _Pid} -> Fun(Conn);
Err ->
Err
Expand Down
2 changes: 1 addition & 1 deletion test/eetcd_lease_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ groups() ->
init_per_suite(Config) ->
application:ensure_all_started(eetcd),
{ok, _Pid} = eetcd:open(?Name, ["127.0.0.1:2379", "127.0.0.1:2479", "127.0.0.1:2579"],
[{mode, random}], tcp, [], []),
[{mode, random}, {transport, tcp}]),
Config.

init_per_testcase(_TestCase, Config) ->
Expand Down
2 changes: 1 addition & 1 deletion test/eetcd_lock_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ groups() ->
init_per_suite(Config) ->
application:ensure_all_started(eetcd),
{ok, _Pid} = eetcd:open(?Name, ["127.0.0.1:2379", "127.0.0.1:2479", "127.0.0.1:2579"],
[{mode, random}], tcp, [], []),
[{mode, random}, {transport, tcp}]),
Config.

init_per_testcase(_TestCase, Config) ->
Expand Down
6 changes: 3 additions & 3 deletions test/eetcd_maintenance_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ end_per_suite(Config) ->
%%%===================================================================

smoke_test(_Config) ->
{ok, _} = eetcd_maintenance:defragment(?Endpoint, tcp, [], []),
{ok, _} = eetcd_maintenance:status(?Endpoint, tcp, [], []),
{ok, _} = eetcd_maintenance:hash_kv(?Endpoint, tcp, [], [], 0),
{ok, _} = eetcd_maintenance:defragment(?Endpoint, [{transport, tcp}]),
{ok, _} = eetcd_maintenance:status(?Endpoint, [{transport, tcp}]),
{ok, _} = eetcd_maintenance:hash_kv(?Endpoint, [{transport, tcp}], 0),
ok.

%%%===================================================================
Expand Down

0 comments on commit 9c672d2

Please sign in to comment.