Skip to content
Draft

wip #631

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
124 changes: 124 additions & 0 deletions src/eqwalizer_specs.erl
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
-module(eqwalizer_specs).
-compile(warn_missing_spec).
% elp:ignore W0054 (no_nowarn_suppressions)
-compile([export_all, nowarn_export_all]).


-spec 'erpc:call'(node(), module(), atom(), [term()]) -> dynamic().
'erpc:call'(_, _, _, _) -> error(eqwalizer_specs).

-spec 'lists:foldl'(fun((T, Acc) -> Acc), Acc, [T]) -> Acc.
'lists:foldl'(_, _, _) -> error(eqwalizer_specs).

-spec 'lists:foldr'(fun((T, Acc) -> Acc), Acc, [T]) -> Acc.
'lists:foldr'(_, _, _) -> error(eqwalizer_specs).

-spec 'lists:nth'(pos_integer(), [T]) -> T.
'lists:nth'(_, _) -> error(eqwalizer_specs).

-spec 'lists:max'([T]) -> T.
'lists:max'(_) -> error(eqwalizer_specs).

-spec 'lists:sort'([T]) -> [T].
'lists:sort'(_) -> error(eqwalizer_specs).

-spec 'lists:usort'([T]) -> [T].
'lists:usort'(_) -> error(eqwalizer_specs).

-spec 'lists:delete'(T, [T]) -> [T].
'lists:delete'(_, _) -> error(eqwalizer_specs).

-spec 'lists:sort'(fun((T, T) -> boolean()), [T]) -> [T].
'lists:sort'(_, _) -> error(eqwalizer_specs).

-spec 'lists:splitwith'(fun((T) -> boolean()), [T]) -> [T].
'lists:splitwith'(_, _) -> error(eqwalizer_specs).

-spec 'lists:foreach'(fun((T) -> ok), [T]) -> [T].
'lists:foreach'(_, _) -> error(eqwalizer_specs).

-spec 'lists:reverse'([T]) -> [T].
'lists:reverse'(_) -> error(eqwalizer_specs).

-spec 'lists:reverse'([T], [T]) -> [T].
'lists:reverse'(_, _) -> error(eqwalizer_specs).

-spec 'erlang:hd'([A, ...]) -> A.
'erlang:hd'(_) -> error(eqwalizer_specs).

-spec 'erlang:max'(A, B) -> A | B.
'erlang:max'(_, _) -> error(eqwalizer_specs).

-spec 'erlang:min'(A, B) -> A | B.
'erlang:min'(_, _) -> error(eqwalizer_specs).

-spec 'erlang:system_time'() -> pos_integer().
'erlang:system_time'() -> error(eqwalizer_specs).

-spec 'erlang:system_time'(erlang:time_unit()) -> pos_integer().
'erlang:system_time'(_) -> error(eqwalizer_specs).

%% -------- gen_statem --------

-spec 'gen_statem:call'(gen_statem:server_ref(), term()) -> dynamic().
'gen_statem:call'(_, _) -> error(eqwalizer_specs).

-spec 'gen_statem:call'(gen_statem:server_ref(), term(), Timeout) -> dynamic() when
Timeout :: timeout() | {clean_timeout, timeout()} | {dirty_timeout, timeout()}.
'gen_statem:call'(_, _, _) -> error(eqwalizer_specs).

-spec 'gen_statem:receive_response'(gen_statem:request_id(), Timeout) ->
dynamic() when
Timeout :: timeout() |
{clean_timeout, timeout()} |
{dirty_timeout, timeout()}.
'gen_statem:receive_response'(_, _) -> error(eqwalizer_specs).

%% -------- application --------

-spec 'application:get_all_env'(App :: atom()) -> [{atom(), dynamic()}].
'application:get_all_env'(_) -> error(eqwalizer_specs).

-spec 'application:get_env'(Param :: atom()) -> undefined | {ok, dynamic()}.
'application:get_env'(_) -> error(eqwalizer_specs).

-spec 'application:get_env'(App :: atom(), Param :: atom()) ->
undefined | {ok, dynamic()}.
'application:get_env'(_, _) -> error(eqwalizer_specs).

-spec 'application:get_env'(App :: atom(), Param :: atom(), Default :: term()) ->
dynamic().
'application:get_env'(_, _, _) -> error(eqwalizer_specs).

-spec 'application:get_key'(Key :: atom()) -> undefined | {ok, dynamic()}.
'application:get_key'(_) -> error(eqwalizer_specs).

-spec 'application:get_key'(App :: atom(), Key :: atom()) -> undefined | {ok, dynamic()}.
'application:get_key'(_, _) -> error(eqwalizer_specs).

-spec 'erlang:binary_to_term'(binary()) -> dynamic().
'erlang:binary_to_term'(_) -> error(eqwalizer_specs).

-spec 'ets:info'
(ets:table(), compressed | decentralized_counters | fixed | named_table | read_concurrency | write_concurrency) ->
boolean();
(ets:table(), binary) -> list();
(ets:table(), heir) -> pid() | none;
(ets:table(), id) -> ets:tid();
(ets:table(), keypos | memory | size) -> non_neg_integer();
(ets:table(), name) -> atom();
(ets:table(), node) -> node();
(ets:table(), owner) -> pid();
(ets:table(), safe_fixed | safe_fixed_monotonic_time) -> tuple() | false;
(ets:table(), stats) -> tuple();
(ets:table(), protection) -> ets:table_access();
(ets:table(), type) -> ets:table_type().
'ets:info'(_, _) -> error(eqwalizer_specs).

%% -------- gen_server --------

-spec 'gen_server:call'(gen_server:server_ref(), term()) -> dynamic().
'gen_server:call'(_, _) -> error(eqwalizer_specs).

-spec 'gen_server:call'(gen_server:server_ref(), term(), timeout()) -> dynamic().
'gen_server:call'(_, _, _) -> error(eqwalizer_specs).
13 changes: 8 additions & 5 deletions src/ra.erl
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
-define(START_TIMEOUT, ?DEFAULT_TIMEOUT).

-type ra_cmd_ret() :: ra_server_proc:ra_cmd_ret().
-type ra_cmd_ret(T) :: ra_server_proc:ra_cmd_ret(T).

-type environment_param() ::
{data_dir, file:filename()} |
Expand Down Expand Up @@ -566,7 +567,7 @@ delete_cluster(ServerIds, Timeout) ->
%% @end
-spec add_member(ra_server_id() | [ra_server_id()],
ra_server_id() | ra_new_server()) ->
ra_cmd_ret() |
ra_cmd_ret(ra_idxterm()) |
{error, already_member} |
{error, cluster_change_not_permitted}.
add_member(ServerLoc, ServerId) ->
Expand All @@ -578,7 +579,7 @@ add_member(ServerLoc, ServerId) ->
-spec add_member(ra_server_id() | [ra_server_id()],
ra_server_id() | ra_new_server(),
timeout()) ->
ra_cmd_ret() |
ra_cmd_ret(ra_idxterm()) |
{error, already_member} |
{error, cluster_change_not_permitted}.
add_member(ServerLoc, ServerId, Timeout) ->
Expand Down Expand Up @@ -661,7 +662,7 @@ leave_and_terminate(System, ServerRef, ServerId) ->
-spec leave_and_terminate(atom(),
ra_server_id() | [ra_server_id()],
ra_server_id(), timeout()) ->
ok | timeout | {error, noproc | system_not_started}.
ok | timeout | {error, nodedown | noproc | system_not_started}.
leave_and_terminate(System, ServerRef, ServerId, Timeout) ->
LeaveCmd = {'$ra_leave', ServerId, await_consensus},
case ra_server_proc:command(ServerRef, LeaveCmd, Timeout) of
Expand Down Expand Up @@ -1101,7 +1102,9 @@ members(ServerId, Timeout) ->
%%
%% @param ServerId the Ra server(s) to send the query to
%% @end
-spec members_info(ra_server_id() | [ra_server_id()] | {local, ra_server_id()}) ->
-spec members_info(ra_server_id() |
[ra_server_id()] |
{local, ra_server_id()}) ->
ra_server_proc:ra_leader_call_ret(ra_cluster()).
members_info(ServerId) ->
members_info(ServerId, ?DEFAULT_TIMEOUT).
Expand All @@ -1120,7 +1123,7 @@ members_info(ServerId) ->
%% @param Timeout the timeout to use
%% @end
-spec members_info(ra_server_id() | [ra_server_id()] | {local, ra_server_id()},
timeout()) ->
timeout()) ->
ra_server_proc:ra_leader_call_ret(ra_cluster()).
members_info({local, ServerId}, Timeout) ->
ra_server_proc:local_state_query(ServerId, members_info, Timeout);
Expand Down
20 changes: 11 additions & 9 deletions src/ra.hrl
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
%%

%% taken from gen_statem as this type isn't exported for some reason.
-type from() ::
{To :: pid(), Tag :: term()}.
-type from() :: gen_statem:from().
% {To :: pid(), Tag :: term()}.

%% Sections 5.1 in the paper.
-type ra_index() :: non_neg_integer().
Expand Down Expand Up @@ -232,6 +232,8 @@
true -> ?DISPATCH_LOG(debug, Fmt, Args);
false -> ok
end).

% eqwalizer:ignore we know what this is
-define(DEBUG(Fmt, Args), ?DISPATCH_LOG(debug, Fmt, Args)).
-define(INFO(Fmt, Args), ?DISPATCH_LOG(info, Fmt, Args)).
-define(NOTICE(Fmt, Args), ?DISPATCH_LOG(notice, Fmt, Args)).
Expand All @@ -243,13 +245,13 @@
-define(DISPATCH_LOG(Level, Fmt, Args),
%% same as OTP logger does when using the macro
try
(persistent_term:get('$ra_logger')):log(Level, Fmt, Args,
#{mfa => {?MODULE,
?FUNCTION_NAME,
?FUNCTION_ARITY},
file => ?FILE,
line => ?LINE,
domain => [ra]})
(ra_env:logger_mod()):log(Level, Fmt, Args,
#{mfa => {?MODULE,
?FUNCTION_NAME,
?FUNCTION_ARITY},
file => ?FILE,
line => ?LINE,
domain => [ra]})
catch
_:_ -> ok
end,
Expand Down
23 changes: 20 additions & 3 deletions src/ra_env.erl
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,26 @@
-export([
data_dir/0,
server_data_dir/2,
configure_logger/1
configure_logger/1,
logger_mod/0,
log/1
]).

-export_type([
]).

-spec data_dir() -> file:filename_all().
data_dir() ->
DataDir = case application:get_env(ra, data_dir) of
{ok, Dir} ->
{ok, Dir} when is_list(Dir) orelse
is_binary(Dir) ->
Dir;
undefined ->
{ok, Cwd} = file:get_cwd(),
Cwd
end,
Node = ra_lib:to_list(node()),
% eqwalizer:ignore we can't validate the DataDir any further
filename:join(DataDir, Node).

server_data_dir(System, UId) when is_atom(System) ->
Expand All @@ -32,5 +37,17 @@ server_data_dir(System, UId) when is_atom(System) ->
filename:join(Dir, Me).

%% use this when interacting with Ra from a node without Ra running on it
configure_logger(Module) ->
configure_logger(Module) when is_atom(Module) ->
persistent_term:put('$ra_logger', Module).

-spec logger_mod() -> module().
logger_mod() ->
case persistent_term:get('$ra_logger', undefined) of
M when is_atom(M) ->
M;
undefined ->
?MODULE
end.

%% dummy log function
log(_) -> ok.
8 changes: 4 additions & 4 deletions src/ra_flru.erl
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@

-define(MAX_SIZE, 5).

-type kv_item() :: {Key :: term(), Value :: term()}.
-type kv_item() :: {Key :: dynamic(), Value :: dynamic()}.

-type handler_fun() :: fun((kv_item()) -> ok).

-record(?MODULE, {max_size = ?MAX_SIZE :: non_neg_integer(),
items = [] :: [term()],
items = [] :: [dynamic()],
handler = fun (_) -> ok end :: handler_fun()}).

-opaque state() :: #?MODULE{}.
Expand All @@ -43,7 +43,7 @@ new(MaxSize, Handler) ->
max_size = MaxSize}.

-spec fetch(term(), state()) ->
{ok, term(), state()} | error.
{ok, dynamic(), state()} | error.
fetch(Key, #?MODULE{items = [{Key, Value} | _]} = State) ->
%% head optimisation
{ok, Value, State};
Expand All @@ -55,7 +55,7 @@ fetch(Key, #?MODULE{items = Items0} = State0) ->
error
end.

-spec insert(term(), term(), state()) -> state().
-spec insert(dynamic(), dynamic(), state()) -> state().
insert(Key, Value, #?MODULE{items = Items,
max_size = M,
handler = Handler} = State)
Expand Down
27 changes: 22 additions & 5 deletions src/ra_lib.erl
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,9 @@
is_any_file/1,
ensure_dir/1,
consult/1,
cons/2
cons/2,
max/2,
unwrap/1
]).

-type file_err() :: file:posix() | badarg | terminated | system_limit.
Expand Down Expand Up @@ -122,11 +124,13 @@ to_binary(I) when is_integer(I) ->
to_binary(L) when is_list(L) ->
list_to_binary(L).

-spec to_string(binary() | string()) -> string().
-spec to_string(binary() | string() | atom()) -> string().
to_string(B) when is_binary(B) ->
binary_to_list(B);
to_string(L) when is_list(L) ->
L.
L;
to_string(A) when is_atom(A) ->
atom_to_list(A).

-spec to_atom(atom() | list() | binary()) -> atom().
to_atom(A) when is_atom(A) ->
Expand Down Expand Up @@ -251,13 +255,15 @@ throw_error(Format, Args) ->
make_uid() ->
make_uid(<<>>).

-spec make_uid(atom() | binary() | string()) -> binary().
-spec make_uid(atom() | binary() | string() | unicode:chardata()) ->
binary().
make_uid(Prefix0) ->
ChrsSize = tuple_size(?GENERATED_UID_CHARS),
F = fun(_, R) ->
[element(rand:uniform(ChrsSize), ?GENERATED_UID_CHARS) | R]
end,
Prefix = to_binary(Prefix0),
% eqwalizer:ignore
B = list_to_binary(lists:foldl(F, "", lists:seq(1, ?UID_LENGTH))),
<<Prefix/binary, B/binary>>.

Expand Down Expand Up @@ -566,6 +572,16 @@ tokens(Str) ->
{error, Err}
end.

-spec max(integer(), integer()) -> integer().
max(A, B) when is_integer(A) andalso
is_integer(B) andalso
A < B -> B;
max(A, _) when is_integer(A) -> A.

unwrap(undefined) ->
error(unwrap_unexpected_undefined);
unwrap(T) ->
T.

-ifdef(TEST).
-include_lib("eunit/include/eunit.hrl").
Expand Down Expand Up @@ -642,7 +658,8 @@ lists_detect_sort_test() ->
partition_parallel_test() ->
?assertMatch({error, {partition_parallel_timeout, [], []}},
partition_parallel(fun(_) ->
timer:sleep(infinity)
timer:sleep(infinity),
true
end, [1, 2, 3], 1000)),
ok.

Expand Down
Loading
Loading