-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, pid_from_dynamic/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(EKU) :: {sender, pid_(), gleam@option:option(fun((EKU) -> 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(EKW) :: {callee_down, gleam@dynamic:dynamic()} | call_timeout | {gleam_phantom, EKW}. -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(ELD), receiver(ELD)}. 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 pid_from_dynamic(gleam@dynamic:dynamic()) -> {ok, pid_()} | {error, list(gleam@dynamic:decode_error())}. pid_from_dynamic(A) -> gleam_otp_external:pid_from_dynamic(A). -spec send(sender(ELP), ELP) -> sender(ELP). 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(ELW)) -> ELW. 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(EMA), receiver(EMA)) -> receiver(EMA). 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(EMO), integer()) -> {ok, EMO} | {error, nil}. 'receive'(A, B) -> gleam_otp_external:run_receiver(A, B). -spec map_receiver(receiver(EMU), fun((EMU) -> EMS)) -> receiver(EMS). map_receiver(A, B) -> gleam_otp_external:map_receiver(A, B). -spec map_sender(sender(EMW), fun((EMY) -> EMW)) -> sender(EMY). 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(ENA), fun((sender(ENC)) -> ENA), integer()) -> {ok, ENC} | {error, call_error(ENC)}. 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(ENH), fun((sender(ENJ)) -> ENH), integer()) -> ENJ. 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 => 475}) 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(ENN), integer(), ENN) -> 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_(), ENP) -> ENP. untyped_send(A, B) -> erlang:send(A, B).