Packages
gleam_erlang
0.10.0
1.3.0
1.2.0
1.1.0
1.0.0
1.0.0-rc1
0.34.0
0.33.0
0.32.0
0.31.0
0.30.0
0.29.0
0.28.0
0.27.0
0.26.0
0.25.0
0.24.0
0.23.1
0.23.0
0.22.0
0.21.0
0.20.0
0.19.0
0.18.1
0.18.0
0.18.0-rc1
retired
0.17.1
0.17.0
0.16.0
0.15.0
0.14.0
0.13.0
0.12.0
0.11.0
0.10.0
0.9.3
0.9.2
0.9.1
0.9.0
0.8.0
0.7.0
0.6.0
0.5.0
0.4.0
0.3.0
0.2.0
0.1.0
Types and functions for programs running on Erlang!
Current section
Files
Jump to
Current section
Files
src/gleam@erlang@process.erl
-module(gleam@erlang@process).
-compile(no_auto_import).
-export([self/0, start/2, new_subject/0, subject_owner/1, send/2, 'receive'/2, new_selector/0, select/2, selecting/3, selecting_subjectless_record/4, sleep/1, sleep_forever/0, is_alive/1, monitor_process/1, selecting_process_down/3, demonitor_process/1, try_call/3, call/3]).
-export_type([pid_/0, subject/1, do_not_leak/0, selector/1, process_monitor_flag/0, process_monitor/0, process_down/0, call_error/1]).
-type pid_() :: any().
-opaque subject(EKU) :: {subject, pid_(), gleam@erlang:reference_()} |
{gleam_phantom, EKU}.
-type do_not_leak() :: any().
-type selector(Payload) :: any() | {gleam_phantom, Payload}.
-type process_monitor_flag() :: process.
-opaque process_monitor() :: {process_monitor, gleam@erlang:reference_()}.
-type process_down() :: {process_down, pid_(), gleam@dynamic:dynamic()}.
-type call_error(EKW) :: {callee_down, gleam@dynamic:dynamic()} |
call_timeout |
{gleam_phantom, EKW}.
-spec self() -> pid_().
self() ->
erlang:self().
-spec start(fun(() -> any()), boolean()) -> pid_().
start(Implementation, Link) ->
case Link of
true ->
erlang:spawn_link(Implementation);
false ->
erlang:spawn(Implementation)
end.
-spec new_subject() -> subject(any()).
new_subject() ->
{subject, erlang:self(), gleam@erlang:make_reference()}.
-spec subject_owner(subject(any())) -> pid_().
subject_owner(Subject) ->
erlang:element(2, Subject).
-spec send(subject(ELF), ELF) -> nil.
send(Subject, Message) ->
erlang:send(
erlang:element(2, Subject),
{erlang:element(3, Subject), Message}
),
nil.
-spec 'receive'(subject(ELH), integer()) -> {ok, ELH} | {error, nil}.
'receive'(Subject, Milliseconds) ->
_pipe = gleam_erlang_ffi:new_selector(),
_pipe@1 = selecting(_pipe, Subject, fun(X) -> X end),
gleam_erlang_ffi:select(_pipe@1, Milliseconds).
-spec new_selector() -> selector(any()).
new_selector() ->
gleam_erlang_ffi:new_selector().
-spec select(selector(ELN), integer()) -> {ok, ELN} | {error, nil}.
select(A, B) ->
gleam_erlang_ffi:select(A, B).
-spec selecting(selector(ELR), subject(ELT), fun((ELT) -> ELR)) -> selector(ELR).
selecting(Selector, Subject, Transform) ->
Handler = fun(Message) -> Transform(erlang:element(2, Message)) end,
gleam_erlang_ffi:insert_selector_handler(
Selector,
{erlang:element(3, Subject), 2},
Handler
).
-spec selecting_subjectless_record(
selector(ELW),
any(),
integer(),
fun((gleam@dynamic:dynamic()) -> ELW)
) -> selector(ELW).
selecting_subjectless_record(Selector, Tag, Size, Transform) ->
gleam_erlang_ffi:insert_selector_handler(Selector, {Tag, Size}, Transform).
-spec sleep(integer()) -> nil.
sleep(A) ->
gleam_erlang_ffi:sleep(A).
-spec sleep_forever() -> nil.
sleep_forever() ->
gleam_erlang_ffi:sleep_forever().
-spec is_alive(pid_()) -> boolean().
is_alive(A) ->
erlang:is_process_alive(A).
-spec monitor_process(pid_()) -> process_monitor().
monitor_process(Pid) ->
_pipe = process,
_pipe@1 = erlang:monitor(_pipe, Pid),
{process_monitor, _pipe@1}.
-spec selecting_process_down(
selector(EMF),
process_monitor(),
fun((process_down()) -> EMF)
) -> selector(EMF).
selecting_process_down(Selector, Monitor, Mapping) ->
gleam_erlang_ffi:insert_selector_handler(
Selector,
erlang:element(2, Monitor),
Mapping
).
-spec demonitor_process(process_monitor()) -> nil.
demonitor_process(A) ->
gleam_erlang_ffi:demonitor(A).
-spec try_call(subject(EMI), fun((subject(EMK)) -> EMI), integer()) -> {ok, EMK} |
{error, call_error(EMK)}.
try_call(Subject, Make_request, Timeout) ->
Reply_subject = new_subject(),
Monitor = monitor_process(subject_owner(Subject)),
send(Subject, Make_request(Reply_subject)),
Result = begin
_pipe = gleam_erlang_ffi:new_selector(),
_pipe@1 = selecting(_pipe, Reply_subject, fun(A) -> {ok, A} end),
_pipe@2 = selecting_process_down(
_pipe@1,
Monitor,
fun(Down) -> {error, {callee_down, erlang:element(3, Down)}} end
),
gleam_erlang_ffi:select(_pipe@2, Timeout)
end,
gleam_erlang_ffi:demonitor(Monitor),
case Result of
{error, nil} ->
{error, call_timeout};
{ok, Res} ->
Res
end.
-spec call(subject(EMP), fun((subject(EMR)) -> EMP), integer()) -> EMR.
call(Subject, Make_request, Timeout) ->
{ok, Resp@1} = case try_call(Subject, Make_request, Timeout) of
{ok, Resp} -> {ok, Resp};
_try ->
erlang:error(#{gleam_error => assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _try,
module => <<"gleam/erlang/process"/utf8>>,
function => <<"call"/utf8>>,
line => 371})
end,
Resp@1.