Commit 380bdf3c authored by Guilherme Andrade's avatar Guilherme Andrade

Tentatively improve semantics of `:wait_for_loaders/2`

parent 3f8354ed
......@@ -278,12 +278,11 @@ wait_for_loader(DatabaseId) ->
%% </ul>
%% @see wait_for_loader/1
%% @see start_loader/2
-spec wait_for_loader(DatabaseId, Timeout) -> {ok, LoadedVersion} | {error, Error}
-spec wait_for_loader(DatabaseId, Timeout) -> {ok, LoadedVersion} | {error, Reason}
when DatabaseId :: atom(),
Timeout :: timeout(),
LoadedVersion :: database_version(),
Error :: database_unknown | timeout | {loading, LoadingError},
LoadingError :: term().
Reason :: database_unknown | {loading,term()} | timeout.
wait_for_loader(DatabaseId, Timeout) ->
case wait_for_loaders([DatabaseId], Timeout) of
{ok, #{DatabaseId := LoadedVersion}} ->
......@@ -315,8 +314,8 @@ wait_for_loader(DatabaseId, Timeout) ->
Timeout :: timeout(),
LoadedVersionPerDatabase :: #{DatabaseId => LoadedVersion},
LoadedVersion :: database_version(),
Reason :: {DatabaseId, DatabaseErrorReason} | timeout,
DatabaseErrorReason :: {loading, term()}.
Reason ::{DatabaseId,LoaderFailure} | timeout,
LoaderFailure :: database_unknown | {loading,term()}.
wait_for_loaders(DatabaseIds, Timeout) ->
{WaiterPid, WaiterMon} = locus_waiter:start(DatabaseIds, Timeout),
case perform_wait(WaiterPid, WaiterMon) of
......@@ -519,9 +518,9 @@ perform_wait(WaiterPid, WaiterMon) ->
handle_waiter_result({ok, LoadedVersionPerDatabase}) ->
{ok, LoadedVersionPerDatabase};
handle_waiter_result({error, DatabaseId, Reason}) ->
handle_waiter_result({error, {DatabaseId, Reason}}) ->
{error, {DatabaseId, Reason}};
handle_waiter_result({down, DatabaseId, Reason}) ->
handle_waiter_result({error, {stopped, DatabaseId, Reason}}) ->
case Reason of
noproc ->
{error, {DatabaseId, database_unknown}};
......@@ -534,5 +533,5 @@ handle_waiter_result({down, DatabaseId, Reason}) ->
_ ->
exit(Reason)
end;
handle_waiter_result(timeout) ->
handle_waiter_result({error, timeout}) ->
{error, timeout}.
......@@ -50,7 +50,7 @@ start(DatabaseIds, Timeout) ->
%% ------------------------------------------------------------------
run_waiter(OwnerPid, DatabaseIds, Timeout) ->
_ = (Timeout =/= infinity andalso erlang:send_after(Timeout, self(), timeout)),
_ = maybe_schedule_timeout(Timeout),
OwnerMon = monitor(process, OwnerPid),
WaitRefs = lists:map(fun locus_database:enqueue_waiter/1, DatabaseIds),
WaitList = lists:zip(WaitRefs, DatabaseIds),
......@@ -67,19 +67,19 @@ run_waiter_loop(OwnerPid, OwnerMon, WaitList, Successes) ->
handle_msg(Msg, OwnerPid, OwnerMon, WaitList, Successes) ->
case Msg of
timeout ->
_ = OwnerPid ! {self(), {error, timeout}},
exit(normal);
{'DOWN', OwnerMon, _, _, _} ->
exit(normal);
{'DOWN', Ref, _, _, Reason} ->
{_,DatabaseId} = lists:keyfind(Ref, 1, WaitList),
_ = OwnerPid ! {self(), {down, DatabaseId, Reason}},
exit(normal);
timeout ->
_ = OwnerPid ! {self(), timeout},
_ = OwnerPid ! {self(), {error, {stopped, DatabaseId, Reason}}},
exit(normal);
{Ref, {error,Reason}}
when is_reference(Ref) ->
{_,DatabaseId} = lists:keyfind(Ref, 1, WaitList),
_ = OwnerPid ! {self(), {error, DatabaseId, Reason}},
_ = OwnerPid ! {self(), {error, {DatabaseId, Reason}}},
exit(normal);
{Ref, {ok,Version}}
when is_reference(Ref) ->
......@@ -88,3 +88,11 @@ handle_msg(Msg, OwnerPid, OwnerMon, WaitList, Successes) ->
UpdatedSuccesses = Successes#{ DatabaseId => Version },
run_waiter_loop(OwnerPid, OwnerMon, UpdatedWaitList, UpdatedSuccesses)
end.
maybe_schedule_timeout(infinity) ->
no;
maybe_schedule_timeout(0) ->
_ = self() ! timeout,
now;
maybe_schedule_timeout(Timeout) ->
erlang:send_after(Timeout, self(), timeout).
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment