Current section

Files

Jump to
gleam_erlang src gleam@erlang@process.erl
Raw

src/gleam@erlang@process.erl

-module(gleam@erlang@process).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-export([self/0, start/2, new_subject/0, subject_owner/1, send/2, 'receive'/2, receive_forever/1, new_selector/0, select/2, select_forever/1, map_selector/2, merge_selector/2, flush_messages/0, selecting_trapped_exits/2, selecting/3, selecting_record2/3, selecting_record3/3, selecting_record4/3, selecting_record5/3, selecting_record6/3, selecting_record7/3, selecting_record8/3, selecting_anything/2, deselecting/2, sleep/1, sleep_forever/0, is_alive/1, monitor_process/1, selecting_process_down/3, demonitor_process/1, deselecting_process_down/2, try_call/3, call/3, try_call_forever/2, call_forever/2, link/1, unlink/1, send_after/3, cancel_timer/1, kill/1, send_exit/1, send_abnormal_exit/2, trap_exits/1, register/2, unregister/1, named/1, pid_from_dynamic/1]).
-export_type([pid_/0, subject/1, do_not_leak/0, selector/1, exit_message/0, exit_reason/0, anything_selector_tag/0, process_monitor_flag/0, process_monitor/0, process_down/0, call_error/1, timer/0, cancelled/0, kill_flag/0]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
-type pid_() :: any().
-opaque subject(FBZ) :: {subject, pid_(), gleam@erlang:reference_()} |
{gleam_phantom, FBZ}.
-type do_not_leak() :: any().
-type selector(FCA) :: any() | {gleam_phantom, FCA}.
-type exit_message() :: {exit_message, pid_(), exit_reason()}.
-type exit_reason() :: normal | killed | {abnormal, binary()}.
-type anything_selector_tag() :: anything.
-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(FCB) :: {callee_down, gleam@dynamic:dynamic_()} |
call_timeout |
{gleam_phantom, FCB}.
-type timer() :: any().
-type cancelled() :: timer_not_found | {cancelled, integer()}.
-type kill_flag() :: kill.
-file("/Users/louis/src/gleam/erlang/src/gleam/erlang/process.gleam", 15).
?DOC(" Get the `Pid` for the current process.\n").
-spec self() -> pid_().
self() ->
erlang:self().
-file("/Users/louis/src/gleam/erlang/src/gleam/erlang/process.gleam", 29).
?DOC(
" Create a new Erlang process that runs concurrently to the creator. In other\n"
" languages this might be called a fibre, a green thread, or a coroutine.\n"
"\n"
" If `linked` is `True` then the created process is linked to the creator\n"
" process. When a process terminates an exit signal is sent to all other\n"
" processes that are linked to it, causing the process to either terminate or\n"
" have to handle the signal.\n"
"\n"
" More can be read about processes and links in the [Erlang documentation][1].\n"
"\n"
" [1]: https://www.erlang.org/doc/reference_manual/processes.html\n"
).
-spec start(fun(() -> any()), boolean()) -> pid_().
start(Implementation, Link) ->
case Link of
true ->
erlang:spawn_link(Implementation);
false ->
erlang:spawn(Implementation)
end.
-file("/Users/louis/src/gleam/erlang/src/gleam/erlang/process.gleam", 71).
?DOC(" Create a new `Subject` owned by the current process.\n").
-spec new_subject() -> subject(any()).
new_subject() ->
{subject, erlang:self(), erlang:make_ref()}.
-file("/Users/louis/src/gleam/erlang/src/gleam/erlang/process.gleam", 78).
?DOC(
" Get the owner process for a `Subject`. This is the process that created the\n"
" `Subject` and will receive messages sent with it.\n"
).
-spec subject_owner(subject(any())) -> pid_().
subject_owner(Subject) ->
erlang:element(2, Subject).
-file("/Users/louis/src/gleam/erlang/src/gleam/erlang/process.gleam", 111).
?DOC(
" Send a message to a process using a `Subject`. The message must be of the\n"
" type that the `Subject` accepts.\n"
"\n"
" This function does not wait for the `Subject` owner process to call the\n"
" `receive` function, instead it returns once the message has been placed in\n"
" the process' mailbox.\n"
"\n"
" # Ordering\n"
"\n"
" If process P1 sends two messages to process P2 it is guaranteed that process\n"
" P1 will receive the messages in the order they were sent.\n"
"\n"
" If you wish to receive the messages in a different order you can send them\n"
" on two different subjects and the receiver function can call the `receive`\n"
" function for each subject in the desired order, or you can write some Erlang\n"
" code to perform a selective receive.\n"
"\n"
" # Examples\n"
"\n"
" ```gleam\n"
" let subject = new_subject()\n"
" send(subject, \"Hello, Joe!\")\n"
" ```\n"
).
-spec send(subject(FCK), FCK) -> nil.
send(Subject, Message) ->
erlang:send(
erlang:element(2, Subject),
{erlang:element(3, Subject), Message}
),
nil.
-file("/Users/louis/src/gleam/erlang/src/gleam/erlang/process.gleam", 132).
?DOC(
" Receive a message that has been sent to current process using the `Subject`.\n"
"\n"
" If there is not an existing message for the `Subject` in the process'\n"
" mailbox or one does not arrive `within` the permitted timeout then the\n"
" `Error(Nil)` is returned.\n"
"\n"
" Only the process that is owner of the `Subject` can receive a message using\n"
" it. If a process that does not own the `Subject` attempts to receive with it\n"
" then it will not receive a message.\n"
"\n"
" To wait for messages from multiple `Subject`s at the same time see the\n"
" `Selector` type.\n"
"\n"
" The `within` parameter specifies the timeout duration in milliseconds.\n"
).
-spec 'receive'(subject(FCM), integer()) -> {ok, FCM} | {error, nil}.
'receive'(Subject, Timeout) ->
gleam_erlang_ffi:'receive'(Subject, Timeout).
-file("/Users/louis/src/gleam/erlang/src/gleam/erlang/process.gleam", 141).
?DOC(
" Receive a message that has been sent to current process using the `Subject`.\n"
"\n"
" Same as `receive` but waits forever and returns the message as is.\n"
).
-spec receive_forever(subject(FCQ)) -> FCQ.
receive_forever(Subject) ->
gleam_erlang_ffi:'receive'(Subject).
-file("/Users/louis/src/gleam/erlang/src/gleam/erlang/process.gleam", 170).
?DOC(
" Create a new `Selector` which can be used to receive messages on multiple\n"
" `Subject`s at once.\n"
).
-spec new_selector() -> selector(any()).
new_selector() ->
gleam_erlang_ffi:new_selector().
-file("/Users/louis/src/gleam/erlang/src/gleam/erlang/process.gleam", 190).
?DOC(
" Receive a message that has been sent to current process using any of the\n"
" `Subject`s that have been added to the `Selector` with the `selecting`\n"
" function.\n"
"\n"
" If there is not an existing message for the `Selector` in the process'\n"
" mailbox or one does not arrive `within` the permitted timeout then the\n"
" `Error(Nil)` is returned.\n"
"\n"
" Only the process that is owner of the `Subject`s can receive a message using\n"
" them. If a process that does not own the a `Subject` attempts to receive\n"
" with it then it will not receive a message.\n"
"\n"
" To wait forever for the next message rather than for a limited amount of\n"
" time see the `select_forever` function.\n"
"\n"
" The `within` parameter specifies the timeout duration in milliseconds.\n"
).
-spec select(selector(FCU), integer()) -> {ok, FCU} | {error, nil}.
select(From, Within) ->
gleam_erlang_ffi:select(From, Within).
-file("/Users/louis/src/gleam/erlang/src/gleam/erlang/process.gleam", 199).
?DOC(
" Similar to the `select` function but will wait forever for a message to\n"
" arrive rather than timing out after a specified amount of time.\n"
).
-spec select_forever(selector(FCY)) -> FCY.
select_forever(From) ->
gleam_erlang_ffi:select(From).
-file("/Users/louis/src/gleam/erlang/src/gleam/erlang/process.gleam", 208).
?DOC(
" Add a transformation function to a selector. When a message is received\n"
" using this selector the transformation function is applied to the message.\n"
"\n"
" This function can be used to change the type of messages received and may\n"
" be useful when combined with the `merge_selector` function.\n"
).
-spec map_selector(selector(FDA), fun((FDA) -> FDC)) -> selector(FDC).
map_selector(A, B) ->
gleam_erlang_ffi:map_selector(A, B).
-file("/Users/louis/src/gleam/erlang/src/gleam/erlang/process.gleam", 217).
?DOC(
" Merge one selector into another, producing a selector that contains the\n"
" message handlers of both.\n"
"\n"
" If a subject is handled by both selectors the handler function of the\n"
" second selector is used.\n"
).
-spec merge_selector(selector(FDE), selector(FDE)) -> selector(FDE).
merge_selector(A, B) ->
gleam_erlang_ffi:merge_selector(A, B).
-file("/Users/louis/src/gleam/erlang/src/gleam/erlang/process.gleam", 261).
?DOC(
" Discard all messages in the current process' mailbox.\n"
"\n"
" Warning: This function may cause other processes to crash if they sent a\n"
" message to the current process and are waiting for a response, so use with\n"
" caution.\n"
).
-spec flush_messages() -> nil.
flush_messages() ->
gleam_erlang_ffi:flush_messages().
-file("/Users/louis/src/gleam/erlang/src/gleam/erlang/process.gleam", 233).
?DOC(
" Add a handler for trapped exit messages. In order for these messages to be\n"
" sent to the process when a linked process exits the process must call the\n"
" `trap_exit` beforehand.\n"
).
-spec selecting_trapped_exits(selector(FDI), fun((exit_message()) -> FDI)) -> selector(FDI).
selecting_trapped_exits(Selector, Handler) ->
Tag = erlang:binary_to_atom(<<"EXIT"/utf8>>),
Handler@1 = fun(Message) ->
Reason = erlang:element(3, Message),
Normal = gleam_stdlib:identity(normal),
Killed = gleam_stdlib:identity(killed),
Reason@2 = case gleam@dynamic@decode:run(
Reason,
{decoder, fun gleam@dynamic@decode:decode_string/1}
) of
_ when Reason =:= Normal ->
normal;
_ when Reason =:= Killed ->
killed;
{ok, Reason@1} ->
{abnormal, Reason@1};
{error, _} ->
{abnormal, gleam@string:inspect(Reason)}
end,
Handler({exit_message, erlang:element(2, Message), Reason@2})
end,
gleam_erlang_ffi:insert_selector_handler(Selector, {Tag, 3}, Handler@1).
-file("/Users/louis/src/gleam/erlang/src/gleam/erlang/process.gleam", 274).
?DOC(
" Add a new `Subject` to the `Selector` so that its messages can be selected\n"
" from the receiver process inbox.\n"
"\n"
" The `mapping` function provided with the `Subject` can be used to convert\n"
" the type of messages received using this `Subject`. This is useful for when\n"
" you wish to add multiple `Subject`s to a `Selector` when they have differing\n"
" message types. If you do not wish to transform the incoming messages in any\n"
" way then the `identity` function can be given.\n"
"\n"
" See `deselecting` to remove a subject from a selector.\n"
).
-spec selecting(selector(FDL), subject(FDN), fun((FDN) -> FDL)) -> selector(FDL).
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
).
-file("/Users/louis/src/gleam/erlang/src/gleam/erlang/process.gleam", 300).
?DOC(
" Add a handler to a selector for 2 element tuple messages with a given tag\n"
" element in the first position.\n"
"\n"
" Typically you want to use the `selecting` function with a `Subject` instead,\n"
" but this function may be useful if you need to receive messages sent from\n"
" other BEAM languages that do not use the `Subject` type.\n"
).
-spec selecting_record2(
selector(FDV),
any(),
fun((gleam@dynamic:dynamic_()) -> FDV)
) -> selector(FDV).
selecting_record2(Selector, Tag, Transform) ->
Handler = fun(Message) -> Transform(erlang:element(2, Message)) end,
gleam_erlang_ffi:insert_selector_handler(Selector, {Tag, 2}, Handler).
-file("/Users/louis/src/gleam/erlang/src/gleam/erlang/process.gleam", 316).
?DOC(
" Add a handler to a selector for 3 element tuple messages with a given tag\n"
" element in the first position.\n"
"\n"
" Typically you want to use the `selecting` function with a `Subject` instead,\n"
" but this function may be useful if you need to receive messages sent from\n"
" other BEAM languages that do not use the `Subject` type.\n"
).
-spec selecting_record3(
selector(FDZ),
any(),
fun((gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_()) -> FDZ)
) -> selector(FDZ).
selecting_record3(Selector, Tag, Transform) ->
Handler = fun(Message) ->
Transform(erlang:element(2, Message), erlang:element(3, Message))
end,
gleam_erlang_ffi:insert_selector_handler(Selector, {Tag, 3}, Handler).
-file("/Users/louis/src/gleam/erlang/src/gleam/erlang/process.gleam", 334).
?DOC(
" Add a handler to a selector for 4 element tuple messages with a given tag\n"
" element in the first position.\n"
"\n"
" Typically you want to use the `selecting` function with a `Subject` instead,\n"
" but this function may be useful if you need to receive messages sent from\n"
" other BEAM languages that do not use the `Subject` type.\n"
).
-spec selecting_record4(
selector(FED),
any(),
fun((gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_()) -> FED)
) -> selector(FED).
selecting_record4(Selector, Tag, Transform) ->
Handler = fun(Message) ->
Transform(
erlang:element(2, Message),
erlang:element(3, Message),
erlang:element(4, Message)
)
end,
gleam_erlang_ffi:insert_selector_handler(Selector, {Tag, 4}, Handler).
-file("/Users/louis/src/gleam/erlang/src/gleam/erlang/process.gleam", 352).
?DOC(
" Add a handler to a selector for 5 element tuple messages with a given tag\n"
" element in the first position.\n"
"\n"
" Typically you want to use the `selecting` function with a `Subject` instead,\n"
" but this function may be useful if you need to receive messages sent from\n"
" other BEAM languages that do not use the `Subject` type.\n"
).
-spec selecting_record5(
selector(FEH),
any(),
fun((gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_()) -> FEH)
) -> selector(FEH).
selecting_record5(Selector, Tag, Transform) ->
Handler = fun(Message) ->
Transform(
erlang:element(2, Message),
erlang:element(3, Message),
erlang:element(4, Message),
erlang:element(5, Message)
)
end,
gleam_erlang_ffi:insert_selector_handler(Selector, {Tag, 5}, Handler).
-file("/Users/louis/src/gleam/erlang/src/gleam/erlang/process.gleam", 370).
?DOC(
" Add a handler to a selector for 6 element tuple messages with a given tag\n"
" element in the first position.\n"
"\n"
" Typically you want to use the `selecting` function with a `Subject` instead,\n"
" but this function may be useful if you need to receive messages sent from\n"
" other BEAM languages that do not use the `Subject` type.\n"
).
-spec selecting_record6(
selector(FEL),
any(),
fun((gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_()) -> FEL)
) -> selector(FEL).
selecting_record6(Selector, Tag, Transform) ->
Handler = fun(Message) ->
Transform(
erlang:element(2, Message),
erlang:element(3, Message),
erlang:element(4, Message),
erlang:element(5, Message),
erlang:element(6, Message)
)
end,
gleam_erlang_ffi:insert_selector_handler(Selector, {Tag, 6}, Handler).
-file("/Users/louis/src/gleam/erlang/src/gleam/erlang/process.gleam", 388).
?DOC(
" Add a handler to a selector for 7 element tuple messages with a given tag\n"
" element in the first position.\n"
"\n"
" Typically you want to use the `selecting` function with a `Subject` instead,\n"
" but this function may be useful if you need to receive messages sent from\n"
" other BEAM languages that do not use the `Subject` type.\n"
).
-spec selecting_record7(
selector(FEP),
any(),
fun((gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_()) -> FEP)
) -> selector(FEP).
selecting_record7(Selector, Tag, Transform) ->
Handler = fun(Message) ->
Transform(
erlang:element(2, Message),
erlang:element(3, Message),
erlang:element(4, Message),
erlang:element(5, Message),
erlang:element(6, Message),
erlang:element(7, Message)
)
end,
gleam_erlang_ffi:insert_selector_handler(Selector, {Tag, 7}, Handler).
-file("/Users/louis/src/gleam/erlang/src/gleam/erlang/process.gleam", 409).
?DOC(
" Add a handler to a selector for 8 element tuple messages with a given tag\n"
" element in the first position.\n"
"\n"
" Typically you want to use the `selecting` function with a `Subject` instead,\n"
" but this function may be useful if you need to receive messages sent from\n"
" other BEAM languages that do not use the `Subject` type.\n"
).
-spec selecting_record8(
selector(FET),
any(),
fun((gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_()) -> FET)
) -> selector(FET).
selecting_record8(Selector, Tag, Transform) ->
Handler = fun(Message) ->
Transform(
erlang:element(2, Message),
erlang:element(3, Message),
erlang:element(4, Message),
erlang:element(5, Message),
erlang:element(6, Message),
erlang:element(7, Message),
erlang:element(8, Message)
)
end,
gleam_erlang_ffi:insert_selector_handler(Selector, {Tag, 8}, Handler).
-file("/Users/louis/src/gleam/erlang/src/gleam/erlang/process.gleam", 459).
?DOC(
" Add a catch-all handler to a selector that will be used when no other\n"
" handler in a selector is suitable for a given message.\n"
"\n"
" This may be useful for when you want to ensure that any message in the inbox\n"
" is handled, or when you need to handle messages from other BEAM languages\n"
" which do not use subjects or record format messages.\n"
).
-spec selecting_anything(selector(FEX), fun((gleam@dynamic:dynamic_()) -> FEX)) -> selector(FEX).
selecting_anything(Selector, Handler) ->
gleam_erlang_ffi:insert_selector_handler(Selector, anything, Handler).
-file("/Users/louis/src/gleam/erlang/src/gleam/erlang/process.gleam", 286).
?DOC(
" Remove a new `Subject` from the `Selector` so that its messages will not be\n"
" selected from the receiver process inbox.\n"
).
-spec deselecting(selector(FDQ), subject(any())) -> selector(FDQ).
deselecting(Selector, Subject) ->
gleam_erlang_ffi:remove_selector_handler(
Selector,
{erlang:element(3, Subject), 2}
).
-file("/Users/louis/src/gleam/erlang/src/gleam/erlang/process.gleam", 483).
?DOC(
" Suspends the process calling this function for the specified number of\n"
" milliseconds.\n"
).
-spec sleep(integer()) -> nil.
sleep(A) ->
gleam_erlang_ffi:sleep(A).
-file("/Users/louis/src/gleam/erlang/src/gleam/erlang/process.gleam", 490).
?DOC(
" Suspends the process forever! This may be useful for suspending the main\n"
" process in a Gleam program when it has no more work to do but we want other\n"
" processes to continue to work.\n"
).
-spec sleep_forever() -> nil.
sleep_forever() ->
gleam_erlang_ffi:sleep_forever().
-file("/Users/louis/src/gleam/erlang/src/gleam/erlang/process.gleam", 499).
?DOC(
" Check to see whether the process for a given `Pid` is alive.\n"
"\n"
" See the [Erlang documentation][1] for more information.\n"
"\n"
" [1]: http://erlang.org/doc/man/erlang.html#is_process_alive-1\n"
).
-spec is_alive(pid_()) -> boolean().
is_alive(A) ->
erlang:is_process_alive(A).
-file("/Users/louis/src/gleam/erlang/src/gleam/erlang/process.gleam", 530).
?DOC(
" Start monitoring a process so that when the monitored process exits a\n"
" message is sent to the monitoring process.\n"
"\n"
" The message is only sent once, when the target process exits. If the\n"
" process was not alive when this function is called the message will never\n"
" be received.\n"
"\n"
" The down message can be received with a `Selector` and the\n"
" `selecting_process_down` function.\n"
"\n"
" The process can be demonitored with the `demonitor_process` function.\n"
).
-spec monitor_process(pid_()) -> process_monitor().
monitor_process(Pid) ->
_pipe = process,
_pipe@1 = erlang:monitor(_pipe, Pid),
{process_monitor, _pipe@1}.
-file("/Users/louis/src/gleam/erlang/src/gleam/erlang/process.gleam", 541).
?DOC(
" Add a `ProcessMonitor` to a `Selector` so that the `ProcessDown` message can\n"
" be received using the `Selector` and the `select` function. The\n"
" `ProcessMonitor` can be removed later with\n"
" [`deselecting_process_down`](#deselecting_process_down).\n"
).
-spec selecting_process_down(
selector(FFJ),
process_monitor(),
fun((process_down()) -> FFJ)
) -> selector(FFJ).
selecting_process_down(Selector, Monitor, Mapping) ->
gleam_erlang_ffi:insert_selector_handler(
Selector,
erlang:element(2, Monitor),
Mapping
).
-file("/Users/louis/src/gleam/erlang/src/gleam/erlang/process.gleam", 555).
?DOC(
" Remove the monitor for a process so that when the monitor process exits a\n"
" `ProcessDown` message is not sent to the monitoring process.\n"
"\n"
" If the message has already been sent it is removed from the monitoring\n"
" process' mailbox.\n"
).
-spec demonitor_process(process_monitor()) -> nil.
demonitor_process(Monitor) ->
gleam_erlang_ffi:demonitor(Monitor),
nil.
-file("/Users/louis/src/gleam/erlang/src/gleam/erlang/process.gleam", 580).
?DOC(
" Remove a `ProcessMonitor` from a `Selector` prevoiusly added by\n"
" [`selecting_process_down`](#selecting_process_down). If the `ProcessMonitor` is not in the\n"
" `Selector` it will be returned unchanged.\n"
).
-spec deselecting_process_down(selector(FFM), process_monitor()) -> selector(FFM).
deselecting_process_down(Selector, Monitor) ->
gleam_erlang_ffi:remove_selector_handler(
Selector,
erlang:element(2, Monitor)
).
-file("/Users/louis/src/gleam/erlang/src/gleam/erlang/process.gleam", 595).
?DOC(
" Send a message to a process and wait for a reply.\n"
"\n"
" If the receiving process exits or does not reply within the allowed amount\n"
" of time then an error is returned.\n"
"\n"
" The `within` parameter specifies the timeout duration in milliseconds.\n"
).
-spec try_call(subject(FFP), fun((subject(FFR)) -> FFP), integer()) -> {ok, FFR} |
{error, call_error(FFR)}.
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(Field@0) -> {ok, Field@0} 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,
demonitor_process(Monitor),
case Result of
{error, nil} ->
{error, call_timeout};
{ok, Res} ->
Res
end.
-file("/Users/louis/src/gleam/erlang/src/gleam/erlang/process.gleam", 636).
?DOC(
" Send a message to a process and wait for a reply.\n"
"\n"
" If the receiving process exits or does not reply within the allowed amount\n"
" of time the calling process crashes. If you wish an error to be returned\n"
" instead see the `try_call` function.\n"
"\n"
" The `within` parameter specifies the timeout duration in milliseconds.\n"
).
-spec call(subject(FFW), fun((subject(FFY)) -> FFW), integer()) -> FFY.
call(Subject, Make_request, Timeout) ->
_assert_subject = try_call(Subject, Make_request, Timeout),
{ok, Resp} = case _assert_subject of
{ok, _} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
value => _assert_fail,
module => <<"gleam/erlang/process"/utf8>>,
function => <<"call"/utf8>>,
line => 641})
end,
Resp.
-file("/Users/louis/src/gleam/erlang/src/gleam/erlang/process.gleam", 665).
?DOC(
" Similar to the `try_call` function but will wait forever for a message\n"
" to arrive rather than timing out after a specified amount of time.\n"
"\n"
" If the receiving process exits then an error is returned.\n"
).
-spec try_call_forever(subject(FGE), fun((subject(FGG)) -> FGE)) -> {ok, FGG} |
{error, call_error(any())}.
try_call_forever(Subject, Make_request) ->
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(Field@0) -> {ok, Field@0} 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)
end,
demonitor_process(Monitor),
Result.
-file("/Users/louis/src/gleam/erlang/src/gleam/erlang/process.gleam", 652).
?DOC(
" Similar to the `call` function but will wait forever for a message to\n"
" arrive rather than timing out after a specified amount of time.\n"
"\n"
" If the receiving process exits, the calling process crashes.\n"
" If you wish an error to be returned instead see the `try_call_forever`\n"
" function.\n"
).
-spec call_forever(subject(FGA), fun((subject(FGC)) -> FGA)) -> FGC.
call_forever(Subject, Make_request) ->
_assert_subject = try_call_forever(Subject, Make_request),
{ok, Response} = case _assert_subject of
{ok, _} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
value => _assert_fail,
module => <<"gleam/erlang/process"/utf8>>,
function => <<"call_forever"/utf8>>,
line => 656})
end,
Response.
-file("/Users/louis/src/gleam/erlang/src/gleam/erlang/process.gleam", 703).
?DOC(
" Creates a link between the calling process and another process.\n"
"\n"
" When a process crashes any linked processes will also crash. This is useful\n"
" to ensure that groups of processes that depend on each other all either\n"
" succeed or fail together.\n"
"\n"
" Returns `True` if the link was created successfully, returns `False` if the\n"
" process was not alive and as such could not be linked.\n"
).
-spec link(pid_()) -> boolean().
link(Pid) ->
gleam_erlang_ffi:link(Pid).
-file("/Users/louis/src/gleam/erlang/src/gleam/erlang/process.gleam", 710).
?DOC(" Removes any existing link between the caller process and the target process.\n").
-spec unlink(pid_()) -> nil.
unlink(Pid) ->
erlang:unlink(Pid),
nil.
-file("/Users/louis/src/gleam/erlang/src/gleam/erlang/process.gleam", 722).
?DOC(" Send a message over a channel after a specified number of milliseconds.\n").
-spec send_after(subject(FGN), integer(), FGN) -> timer().
send_after(Subject, Delay, Message) ->
erlang:send_after(
Delay,
erlang:element(2, Subject),
{erlang:element(3, Subject), Message}
).
-file("/Users/louis/src/gleam/erlang/src/gleam/erlang/process.gleam", 746).
?DOC(" Cancel a given timer, causing it not to trigger if it has not done already.\n").
-spec cancel_timer(timer()) -> cancelled().
cancel_timer(Timer) ->
case gleam@dynamic@decode:run(
erlang:cancel_timer(Timer),
{decoder, fun gleam@dynamic@decode:decode_int/1}
) of
{ok, I} ->
{cancelled, I};
{error, _} ->
timer_not_found
end.
-file("/Users/louis/src/gleam/erlang/src/gleam/erlang/process.gleam", 770).
?DOC(
" Send an untrappable `kill` exit signal to the target process.\n"
"\n"
" See the documentation for the Erlang [`erlang:exit`][1] function for more\n"
" information.\n"
"\n"
" [1]: https://erlang.org/doc/man/erlang.html#exit-1\n"
).
-spec kill(pid_()) -> nil.
kill(Pid) ->
erlang:exit(Pid, kill),
nil.
-file("/Users/louis/src/gleam/erlang/src/gleam/erlang/process.gleam", 786).
?DOC(
" Sends an exit signal to a process, indicating that the process is to shut\n"
" down.\n"
"\n"
" See the [Erlang documentation][1] for more information.\n"
"\n"
" [1]: http://erlang.org/doc/man/erlang.html#exit-2\n"
).
-spec send_exit(pid_()) -> nil.
send_exit(Pid) ->
erlang:exit(Pid, normal),
nil.
-file("/Users/louis/src/gleam/erlang/src/gleam/erlang/process.gleam", 798).
?DOC(
" Sends an exit signal to a process, indicating that the process is to shut\n"
" down due to an abnormal reason such as a failure.\n"
"\n"
" See the [Erlang documentation][1] for more information.\n"
"\n"
" [1]: http://erlang.org/doc/man/erlang.html#exit-2\n"
).
-spec send_abnormal_exit(pid_(), binary()) -> nil.
send_abnormal_exit(Pid, Reason) ->
erlang:exit(Pid, {abnormal, Reason}),
nil.
-file("/Users/louis/src/gleam/erlang/src/gleam/erlang/process.gleam", 814).
?DOC(
" Set whether the current process is to trap exit signals or not.\n"
"\n"
" When not trapping exits if a linked process crashes the exit signal\n"
" propagates to the process which will also crash.\n"
" This is the normal behaviour before this function is called.\n"
"\n"
" When trapping exits (after this function is called) if a linked process\n"
" crashes an exit message is sent to the process instead. These messages can\n"
" be handled with the `selecting_trapped_exits` function.\n"
).
-spec trap_exits(boolean()) -> nil.
trap_exits(A) ->
gleam_erlang_ffi:trap_exits(A).
-file("/Users/louis/src/gleam/erlang/src/gleam/erlang/process.gleam", 826).
?DOC(
" Register a process under a given name, allowing it to be looked up using\n"
" the `named` function.\n"
"\n"
" This function will return an error under the following conditions:\n"
" - The process for the pid no longer exists.\n"
" - The name has already been registered.\n"
" - The process already has a name.\n"
" - The name is the atom `undefined`, which is reserved by Erlang.\n"
).
-spec register(pid_(), gleam@erlang@atom:atom_()) -> {ok, nil} | {error, nil}.
register(Pid, Name) ->
gleam_erlang_ffi:register_process(Pid, Name).
-file("/Users/louis/src/gleam/erlang/src/gleam/erlang/process.gleam", 837).
?DOC(
" Un-register a process name, after which the process can no longer be looked\n"
" up by that name, and both the name and the process can be re-used in other\n"
" registrations.\n"
"\n"
" It is possible to un-register process that are not from your application,\n"
" including those from Erlang/OTP itself. This is not recommended and will\n"
" likely result in undesirable behaviour and crashes.\n"
).
-spec unregister(gleam@erlang@atom:atom_()) -> {ok, nil} | {error, nil}.
unregister(Name) ->
gleam_erlang_ffi:unregister_process(Name).
-file("/Users/louis/src/gleam/erlang/src/gleam/erlang/process.gleam", 842).
?DOC(" Look up a process by name, returning the pid if it exists.\n").
-spec named(gleam@erlang@atom:atom_()) -> {ok, pid_()} | {error, nil}.
named(Name) ->
gleam_erlang_ffi:process_named(Name).
-file("/Users/louis/src/gleam/erlang/src/gleam/erlang/process.gleam", 860).
?DOC(
" Checks to see whether a `Dynamic` value is a pid, and return the pid if\n"
" it is.\n"
"\n"
" ## Examples\n"
"\n"
" ```gleam\n"
" import gleam/dynamic\n"
" pid_from_dynamic(dynamic.from(process.self()))\n"
" // -> Ok(process.self())\n"
" ```\n"
"\n"
" ```gleam\n"
" pid_from_dynamic(dynamic.from(123))\n"
" // -> Error([DecodeError(expected: \"Pid\", found: \"Int\", path: [])])\n"
" ```\n"
).
-spec pid_from_dynamic(gleam@dynamic:dynamic_()) -> {ok, pid_()} |
{error, list(gleam@dynamic@decode:decode_error())}.
pid_from_dynamic(From) ->
gleam_erlang_ffi:pid_from_dynamic(From).