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.

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-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

whereis

(whereis reg-name)
Returns the process identifier with the registered name reg-name,
or nil if the name is not registered.