-module(gleam@otp@process). -compile(no_auto_import). -export([new_reference/0, self/0, system_receiver/0, new_channel/0, new_bare_sender/1, close_channels/1, pid/1, send/2, null_sender/1, monitor_process/1, monitor_port/1, receive_forever/1, flush/1, merge_receiver/2, bare_message_receiver/0, debug_state/1, is_alive/1, kill/1, send_exit/2, start/1, start_unlinked/1, 'receive'/2, map_receiver/2, map_sender/2, try_call/3, call/3, message_queue_size/1, trap_exits/0, stop_trapping_exits/0, send_after/3, cancel_timer/1, link/1, unlink/1, untyped_send/2]). -export_type([pid_/0, reference_/0, sender/1, receiver/1, process_monitor_flag/0, port_monitor_flag/0, process_down/0, port_down/0, exit/0, exit_reason/0, mode/0, debug_option/0, debug_state/0, status_info/0, system_message/0, kill_flag/0, call_error/1, message_queue_len_flag/0, timer/0, cancelled/0]). -type pid_() :: any(). -type reference_() :: any(). -opaque sender(AA) :: {sender, pid_(), gleam@option:option(fun((AA) -> gleam@dynamic:dynamic()))}. -type receiver(Msg) :: any() | {gleam_phantom, Msg}. -type process_monitor_flag() :: process. -type port_monitor_flag() :: port. -type process_down() :: {process_down, pid_(), gleam@dynamic:dynamic()}. -type port_down() :: {port_down, gleam@otp@port:port_(), gleam@dynamic:dynamic()}. -type exit() :: {exit, pid_(), gleam@dynamic:dynamic()}. -type exit_reason() :: normal | shutdown | {abnormal, gleam@dynamic:dynamic()}. -type mode() :: running | suspended. -type debug_option() :: no_debug. -type debug_state() :: any(). -type status_info() :: {status_info, gleam@erlang@atom:atom_(), pid_(), mode(), debug_state(), gleam@dynamic:dynamic()}. -type system_message() :: {get_status, sender(status_info())} | {suspend, sender(nil)} | {resume, sender(nil)} | {get_state, sender(gleam@dynamic:dynamic())}. -type kill_flag() :: kill. -type call_error(AC) :: {callee_down, gleam@dynamic:dynamic()} | call_timeout | {gleam_phantom, AC}. -type message_queue_len_flag() :: message_queue_len. -type timer() :: any(). -type cancelled() :: timer_not_found | {cancelled, integer()}. -spec new_reference() -> reference_(). new_reference() -> erlang:make_ref(). -spec self() -> pid_(). self() -> erlang:self(). -spec system_receiver() -> receiver(system_message()). system_receiver() -> gleam_otp_external:system_receiver(). -spec new_channel() -> {sender(AJ), receiver(AJ)}. new_channel() -> Reference = erlang:make_ref(), Sender = begin _pipe = erlang:self(), _pipe@1 = new_bare_sender(_pipe), map_sender(_pipe@1, fun(Msg) -> {Reference, Msg} end) end, Receiver = gleam_otp_external:new_receiver(Reference), {Sender, Receiver}. -spec new_bare_sender(pid_()) -> sender(any()). new_bare_sender(Pid) -> Prepare = fun(Msg) -> gleam@dynamic:from(Msg) end, {sender, Pid, {some, Prepare}}. -spec close_channels(receiver(any())) -> nil. close_channels(A) -> gleam_otp_external:close_channels(A). -spec pid(sender(any())) -> pid_(). pid(Sender) -> erlang:element(2, Sender). -spec send(sender(AS), AS) -> sender(AS). send(Sender, Message) -> case erlang:element(3, Sender) of {some, Prepare} -> _pipe = Message, _pipe@1 = Prepare(_pipe), erlang:send(erlang:element(2, Sender), _pipe@1), Sender; none -> Sender end. -spec null_sender(pid_()) -> sender(any()). null_sender(Pid) -> {sender, Pid, none}. -spec monitor_process(pid_()) -> receiver(process_down()). monitor_process(Pid) -> Reference = erlang:monitor(process, Pid), gleam_otp_external:new_receiver({process, Reference}). -spec monitor_port(gleam@otp@port:port_()) -> receiver(port_down()). monitor_port(Port) -> Reference = erlang:monitor(port, Port), gleam_otp_external:new_receiver({port, Reference}). -spec receive_forever(receiver(AZ)) -> AZ. receive_forever(A) -> gleam_otp_external:run_receiver_forever(A). -spec flush(receiver(any())) -> integer(). flush(A) -> gleam_otp_external:flush_receiver(A). -spec merge_receiver(receiver(BD), receiver(BD)) -> receiver(BD). merge_receiver(A, B) -> gleam_otp_external:merge_receiver(A, B). -spec bare_message_receiver() -> receiver(gleam@dynamic:dynamic()). bare_message_receiver() -> gleam_otp_external:bare_message_receiver(). -spec debug_state(list(debug_option())) -> debug_state(). debug_state(A) -> sys:debug_options(A). -spec is_alive(pid_()) -> boolean(). is_alive(A) -> erlang:is_process_alive(A). -spec kill(pid_()) -> nil. kill(Pid) -> erlang:exit(Pid, kill), nil. -spec send_exit(pid_(), any()) -> nil. send_exit(Pid, Reason) -> erlang:exit(Pid, Reason), nil. -spec start(fun(() -> any())) -> pid_(). start(A) -> erlang:spawn_link(A). -spec start_unlinked(fun(() -> any())) -> pid_(). start_unlinked(A) -> erlang:spawn(A). -spec 'receive'(receiver(BR), integer()) -> {ok, BR} | {error, nil}. 'receive'(A, B) -> gleam_otp_external:run_receiver(A, B). -spec map_receiver(receiver(BX), fun((BX) -> BV)) -> receiver(BV). map_receiver(A, B) -> gleam_otp_external:map_receiver(A, B). -spec map_sender(sender(BZ), fun((CB) -> BZ)) -> sender(CB). map_sender(Sender, Mapper) -> Wrap = fun(_capture) -> gleam@function:compose(Mapper, _capture) end, Prepare = gleam@option:map(erlang:element(3, Sender), Wrap), {sender, erlang:element(2, Sender), Prepare}. -spec try_call(sender(CD), fun((sender(CF)) -> CD), integer()) -> {ok, CF} | {error, call_error(CF)}. try_call(Sender, Make_request, Timeout) -> {Reply_sender, Reply_receiver} = new_channel(), Monitor = monitor_process(pid(Sender)), send(Sender, Make_request(Reply_sender)), Receiver = begin _pipe = Reply_receiver, _pipe@1 = gleam_otp_external:map_receiver(_pipe, fun(A) -> {ok, A} end), gleam_otp_external:merge_receiver( _pipe@1, gleam_otp_external:map_receiver( Monitor, fun(Down) -> {error, {callee_down, erlang:element(3, Down)}} end ) ) end, Res = gleam_otp_external:run_receiver(Receiver, Timeout), gleam_otp_external:close_channels(Receiver), case Res of {error, nil} -> {error, call_timeout}; {ok, Res@1} -> Res@1 end. -spec call(sender(CK), fun((sender(CM)) -> CK), integer()) -> CM. call(Sender, Make_request, Timeout) -> {ok, Resp@1} = case try_call(Sender, Make_request, Timeout) of {ok, Resp} -> {ok, Resp}; _try -> erlang:error(#{gleam_error => assert, message => <<"Assertion pattern match failed"/utf8>>, value => _try, module => <<"gleam/otp/process"/utf8>>, function => <<"call"/utf8>>, line => 471}) end, Resp@1. -spec message_queue_size(pid_()) -> integer(). message_queue_size(Pid) -> erlang:element(2, erlang:process_info(Pid, message_queue_len)). -spec trap_exits() -> receiver(exit()). trap_exits() -> gleam_otp_external:trap_exits(). -spec stop_trapping_exits() -> nil. stop_trapping_exits() -> gleam_otp_external:stop_trapping_exits(). -spec send_after(sender(CQ), integer(), CQ) -> timer(). send_after(Sender, Delay, Message) -> case erlang:element(3, Sender) of {some, Prepare} -> erlang:send_after( Delay, erlang:element(2, Sender), Prepare(Message) ); none -> erlang:make_ref() end. -spec cancel_timer(timer()) -> cancelled(). cancel_timer(Timer) -> case gleam@dynamic:int(erlang:cancel_timer(Timer)) of {ok, I} -> {cancelled, I}; {error, _@1} -> timer_not_found end. -spec link(pid_()) -> nil. link(Pid) -> erlang:link(Pid), nil. -spec unlink(pid_()) -> nil. unlink(Pid) -> erlang:link(Pid), nil. -spec untyped_send(pid_(), CS) -> CS. untyped_send(A, B) -> erlang:send(A, B).