otplike.process
This namespace implements core process concepts like spawning,
linking, monitoring, message passing, exiting, and other.
Process context
All calls made from process function directly or indirectly after
it has been spawned are made in process context.
Note: for now process context exists until process function finishes
its execution and isn't bound to process exit.
Process exit
- process' inbox becomes closed, so no future messages appear in it
(but those alredy in inbox can be received)
- all linked/monitoring processes receive exit/down signal
- process can not be reached by its pid
- process is no longer registered
As there is no way to force process function to stop execution after
its process has exited, there can be cases when exited process tries
to communicate with other processes. If some function behaves
different in such cases, it should be said in its documentation.
Signals (control messages)
Signals are used internally to manage processes. Exiting, monitoring,
linking and some other operations require sending signals.
Sometimes a lot of signals must be sent to a process simultaneously
(e.g. a process monitors 1000 linked processes and one of them exits).
In such cases control message queue of a process can overflow. When
it happens, the process exits immediately with reason
:control-overflow.
!
(! dest message)
Sends a message to dest. dest can be a process identifier, or a
registered name.
If sending results in dest's inbox overflow, dest exits with reason
:inbox-overflow.
Returns true if message was sent (process was alive), false otherwise.
Throws if any of arguments is nil.
demonitor
(demonitor {:keys [self-pid other-pid], :as mref})
If mref is a reference that the calling process obtained by
calling monitor, this monitoring is turned off. If the monitoring
is already turned off, nothing happens. If mref was created by
other process, nothing happens.
Once demonitor has returned, it is guaranteed that no
[:DOWN monitor-ref _ _ _] message, because of the monitor,
will be placed in the caller message queue in the future.
A [:DOWN monitor-ref _ _ _] message can have been placed in
the caller message queue before the call, though. It is therefore
usually advisable to remove such a :DOWN message from the message
queue after monitoring has been stopped.
Returns true.
Throws when called not in process context, mref is not a
monitor-ref.
ex->reason
(ex->reason e)
Makes exit reason from exception.
ex-catch
macro
(ex-catch expr)
Executes expr. Returns either result of execution or exit reason.
exit
(exit reason)
(exit pid reason)
Sends an exit signal with exit reason to the process identified
by pid.
If reason is any term, except :normal or :kill:
- if pid is not trapping exits, pid itself exits with exit reason.
- if pid is trapping exits, the exit signal is transformed into a
message [:EXIT from reason] and delivered to the message queue
of pid. from is the process identifier of the process that sent
the exit signal.
If reason is :normal, pid does not exit. If pid is trapping exits,
the exit signal is transformed into a message
[:EXIT from :normal] and delivered to its message queue.
If reason is :kill, an untrappable exit signal is sent to pid,
which unconditionally exits with reason :killed.
Returns true if exit signal was sent (process was alive), false
otherwise.
Throws when callen not in process context, if pid is not a pid, or
reason is nil.
flag
(flag flag value)
Sets the value of a process flag. See description of each flag below.
Returns the old value of a flag.
Throws when called not in process context.
:trap-exit
When :trap-exit is set to true, exit signals arriving to a process
are converted to [:EXIT from reason] messages, which can be
received as ordinary messages. If :trap-exit is set to false, the
process exits if it receives an exit signal other than :normal and
the exit signal is propagated to its linked processes. Application
processes are normally not to trap exits.
link
(link pid)
Creates a link between the calling process and another process
identified by pid, if there is not such a link already. If a
process attempts to create a link to itself, nothing is done.
If pid does not exist and the calling process
1. is trapping exits - the calling process receives message
[:EXIT pid :noproc].
2. is not trapping exits - process exits with reason :noproc.
Returns true.
Throws when called not in process context, or by exited process,
or pid is not a pid.
monitor
(monitor pid-or-name)
Sends a monitor request to the entity identified by pid-or-name.
If the monitored entity does not exist or when it dies,
the caller of monitor will be notified by a message of the
following format:
[tag monitor-ref type object info]
type can be one of the following keywords: :process.
A monitor is triggered only once, after that it is removed from
both monitoring process and the monitored entity. Monitors are
fired when the monitored process terminates, or does not
exist at the moment of creation. The monitoring is also turned
off when demonitor/1 is called.
When monitoring by name please note, that the registered-name is
resolved to pid only once at the moment of monitor instantiation,
later changes to the name registration will not affect the existing
monitor.
When a monitor is triggered, a :DOWN message that has the
following pattern
[:DOWN monitor-ref type object info]
is sent to the monitoring process.
In monitor message monitor-ref and type are the same as described
earlier, and:
object
The monitored entity, which triggered the event. That is the
argument of monitor call.
info
Either the exit reason of the process, or :noproc (process did not
exist at the time of monitor creation).
Making several calls to monitor/2 for the same pid-or-name and/or
type is not an error; it results in as many independent monitoring
instances.
Monitoring self does nothing.
Returns monitor-ref.
Throws when called not in process context.
monitor-ref?
(monitor-ref? mref)
Returns true if term is a monitor reference, false otherwise.
pid->str
(pid->str {:keys [id pname], :as pid})
Returns a string corresponding to the text representation of pid.
Throws if pid is not a process identifier.
Warning: this function is intended for debugging and is not to be
used in application programs.
pid?
(pid? pid)
Returns true if term is a process identifier, false otherwise.
proc-defn
macro
(proc-defn fname args & body)
The same as proc-fn but also binds created function to a var with
the name fname.
proc-fn
macro
(proc-fn args & body)
Creates process function which can be passed to spawn.
receive!
macro
(receive! & clauses)
receive!!
macro
(receive!! & clauses)
registered
(registered)
Returns a set of names of the processes that have been registered.
resolve-pid
(resolve-pid pid-or-name)
If pid-or-name is
pid - returns pid,
registered name - returns the pid of registered process,
else returns nil.
self
(self)
Returns the process identifier of the calling process.
Throws when called not in process context.
spawn
(spawn proc-func)
(spawn proc-func args)
Returns the process identifier of a new process started by the
application of proc-fun to args.
spawn-link
(spawn-link proc-func)
(spawn-link proc-func args)
Returns the process identifier of a new process started by the
application of proc-fun to args. A link is created between the
calling process and the new process, atomically. Otherwise works
like spawn.
Throws when called not in process context.
spawn-opt
(spawn-opt proc-func opts)
(spawn-opt proc-func args opts)
Returns the process identifier of a new process started by the
application of proc-fun to args.
options argument is a map of option names (keyword) to its values.
The default process' inbox is blocking buffered channel of size 1024.
The :inbox option allows providing a custom channel.
The following options are allowed:
:flags - a map of process' flags (e.g. {:trap-exit true})
:link - if true, sets a link to the parent process
:register - name to register the process, can not be pid, if name is
nil process will not be registered
:inbox - the channel to be used as a process' inbox
unlink
(unlink pid)
Removes the link, if there is one, between the calling process and
the process referred to by pid.
Returns true.
Does not fail if there is no link to pid, if pid is self pid, or
if pid does not exist.
Once unlink has returned, it is guaranteed that the link between
the caller and the entity referred to by pid has no effect on the
caller in the future (unless the link is setup again).
If the caller is trapping exits, an [:EXIT pid _] message from
the link can have been placed in the caller's message queue before
the call.
Notice that the [:EXIT pid _] message can be the result of the
link, but can also be the result of pid calling exit. Therefore,
it can be appropriate to clean up the message queue when trapping
exits after the call to unlink.
Throws when called not in process context, or called by exited
process, or pid is not a pid.
whereis
(whereis reg-name)
Returns the process identifier with the registered name reg-name,
or nil if the name is not registered.