Current section

Files

Jump to
puddle src puddle.erl
Raw

src/puddle.erl

-module(puddle).
-compile([no_auto_import, nowarn_unused_vars]).
-export([start_manager/2]).
-export_type([usage_message/2, bookkeeping_message/2]).
-type usage_message(GVS, GVT) :: {usage_message,
fun((GVS) -> GVT),
gleam@erlang@process:subject({ok, GVT} | {error, nil})}.
-type bookkeeping_message(GVU, GVV) :: shutdown |
{put_back, gleam@erlang@process:subject(usage_message(GVU, GVV))} |
{checkout,
gleam@erlang@process:subject({ok,
gleam@erlang@process:subject(usage_message(GVU, GVV))} |
{error, nil})}.
-spec handle_bookkeeping_message(
bookkeeping_message(GWT, GWU),
list({gleam@erlang@process:pid_(),
gleam@erlang@process:subject(usage_message(GWT, GWU))})
) -> gleam@otp@actor:next(any(), list({gleam@erlang@process:pid_(),
gleam@erlang@process:subject(usage_message(GWT, GWU))})).
handle_bookkeeping_message(Msg, Puddle) ->
case Msg of
shutdown ->
gleam@list:each(
Puddle,
fun(Item) ->
gleam@erlang@process:kill(erlang:element(1, Item))
end
),
{stop, normal};
{put_back, Subject} ->
Pid = gleam@erlang@process:subject_owner(Subject),
gleam@otp@actor:continue(gleam@list:prepend(Puddle, {Pid, Subject}));
{checkout, Client} ->
case Puddle of
[] ->
gleam@otp@actor:send(Client, {error, nil}),
gleam@otp@actor:continue(Puddle);
[{_, Chosen} | New_puddle] ->
gleam@otp@actor:send(Client, {ok, Chosen}),
gleam@otp@actor:continue(New_puddle)
end
end.
-spec handle_usage_message(usage_message(GXA, any()), GXA) -> gleam@otp@actor:next(any(), GXA).
handle_usage_message(Msg, Resource) ->
case Msg of
{usage_message, Func, Client} ->
Result = Func(Resource),
gleam@otp@actor:send(Client, {ok, Result}),
gleam@otp@actor:continue(Resource)
end.
-spec new(integer(), fun(() -> {ok, GWL} | {error, nil})) -> {ok,
list({gleam@erlang@process:pid_(),
gleam@erlang@process:subject(usage_message(GWL, any()))})} |
{error, nil}.
new(Size, New_resource) ->
_pipe = gleam@list:repeat(<<""/utf8>>, Size),
gleam@list:try_map(_pipe, fun(_) -> case New_resource() of
{ok, Initial_state} ->
_pipe@1 = gleam@otp@actor:start(
Initial_state,
fun handle_usage_message/2
),
_pipe@2 = gleam@result:map(
_pipe@1,
fun(Subject) ->
Pid = gleam@erlang@process:subject_owner(Subject),
{Pid, Subject}
end
),
gleam@result:nil_error(_pipe@2);
{error, nil} ->
{error, nil}
end end).
-spec start_manager(integer(), fun(() -> {ok, GWC} | {error, nil})) -> {ok,
gleam@erlang@process:subject(bookkeeping_message(GWC, any()))} |
{error, nil}.
start_manager(Size, New_resource) ->
gleam@result:then(
new(Size, New_resource),
fun(Puddle) ->
_pipe = gleam@otp@actor:start(
Puddle,
fun handle_bookkeeping_message/2
),
gleam@result:nil_error(_pipe)
end
).