gleam/erlang/process

Types

An error returned when making a call to a process.

pub type CallError(msg) {
  CalleeDown(reason: Dynamic)
  CallTimeout
}

Constructors

  • CalleeDown(reason: Dynamic)

    The process being called exited before it sent a response.

  • CallTimeout

    The process being called did not response within the permitted amount of time.

A Pid (or Process identifier) is a reference to an Erlang process. Each process has a Pid and it is one of the lowest level building blocks of inter-process communication in the Erlang and Gleam OTP frameworks.

pub external type Pid

A message received when a monitored process exits.

pub type ProcessDown {
  ProcessDown(pid: Pid, reason: Dynamic)
}

Constructors

  • ProcessDown(pid: Pid, reason: Dynamic)
pub opaque type ProcessMonitor

A type that enables a process to wait for messages from multiple Subjects at the same time, returning whichever message arrives first.

Used with the new_selector, selecting, and select functions.

Examples

> let int_subject = new_subject()
> let float_subject = new_subject()
> send(int_subject, 1)
>
> let selector =
>   new_selector()
>   |> selecting(int_subject, int.to_string)
>   |> selecting(float_subject, float.to_string)
>
> select(selector)
Ok("1")
pub external type Selector(payload)

A Subject is a value that processes can use to send and receive messages to and from each other in a well typed way.

Each subject is “owned” by the process that created it. Any process can use the send function to sent a message of the correct type to the process that owns the subject, and the owner can use the receive function or the Selector type to receive these messages.

The Subject type is similar to the “channel” types found in other languages and the “topic” concept found in some pub-sub systems.

Examples

let subject = new_subject()

// Send a message with the subject
send(subject, "Hello, Joe!")

// Receive the message
receive(subject, within: 10)
pub opaque type Subject(message)

Functions

pub fn call(subject: Subject(a), make_request: fn(Subject(b)) ->
    a, within timeout: Int) -> b

Send a message to a process and wait for a reply.

If the receiving process exits or does not reply within the allowed amount of time the calling process crashes. If you wish an error to be returned instead see the try_call function.

pub external fn demonitor_process(monitor: ProcessMonitor) -> Nil

Remove the monitor for a process so that when the monitor process exits a ProcessDown message is not sent to the monitoring process.

If the message has already been sent it is removed from the monitoring process’ mailbox.

pub external fn is_alive(Pid) -> Bool

Check to see whether the process for a given Pid is alive.

See the Erlang documentation for more information.

pub fn monitor_process(pid: Pid) -> ProcessMonitor

Start monitoring a process so that when the monitored process exits a message is to the monitoring process.

The message is only sent once, when the target process exits. If the process was not alive when this function is called the message will never be received.

The down message can be received with a Selector and the selecting_process_down function.

The process can be demonitored with the demonitor_process function.

pub external fn new_selector() -> Selector(payload)

Create a new Selector which can be used to receive messages on multiple Subjects at once.

pub fn new_subject() -> Subject(a)

Create a new Subject owned by the current process.

pub fn receive(from subject: Subject(a), within milliseconds: Int) -> Result(
  a,
  Nil,
)

Receive a message that has been sent to current process using the Subject.

If there is not an existing message for the Subject in the process’ mailbox or one does not arrive within the permitted timeout then the Error(Nil) is returned.

Only the process that is owner of the Subject can receive a message using it. If a process that does not own the Subject attempts to receive with it then it will not receive a message.

To wait for messages from multiple Subjects at the same time see the Selector type.

pub external fn select(
  from: Selector(payload),
  within: Int,
) -> Result(payload, Nil)

Receive a message that has been sent to current process using any of the Subjects that have been added to the Selector with the selecting function.

If there is not an existing message for the Selector in the process’ mailbox or one does not arrive within the permitted timeout then the Error(Nil) is returned.

Only the process that is owner of the Subjects can receive a message using them. If a process that does not own the a Subject attempts to receive with it then it will not receive a message.

pub fn selecting(selector: Selector(a), for subject: Subject(b), mapping transform: fn(
    b,
  ) -> a) -> Selector(a)

Add a new Subject to the Selector to that it’s messages can be received.

The mapping function provided with the Subject can be used to convert the type of messages received using this Subject. This is useful for when you wish to add multiple Subjects to a Seletor when they have differing message types. If you do not wish to transform the incoming messages in any way then the identity function can be given.

pub fn selecting_process_down(selector: Selector(a), monitor: ProcessMonitor, mapping: fn(
    ProcessDown,
  ) -> a) -> Selector(a)

Add a ProcessMonitor to a Selector so that the ProcessDown message can be received using the Selector and the select function.

pub fn selecting_subjectless_record(selector: Selector(a), tag: b, size: Int, mapping transform: fn(
    Dynamic,
  ) -> a) -> Selector(a)

Configure a Selector to receive tuple messages that have the specified size and given first element.

This function may be useful when interacting with Erlang code that sends messages for you to receive but does not use Subjects.

For example, if a process has been sent the message #("name", "Lucy") it could be receive like so:

new_selector()
|> selecting_subjectless_record("name", 2, fn(x) { x })
|> select(0)
pub external fn self() -> Pid

Get the Pid for the current process.

pub fn send(subject: Subject(a), message: a) -> Nil

Send a message to a process using a Subject. The message must be of the type that the Subject accepts.

This function does not wait for the Subject owner process to call the receive function, instead it returns once the message has been placed in the process’ mailbox.

Ordering

If process P1 sends two messages to process P2 it is guarenteed that process P1 will receive the messages in the order they were sent.

If you wish to receive the messages in a different order you can send them on two different subjects and the receiver function can call the receive function for each subject in the desired order, or you can write some Erlang code to perform a selective receive.

Examples

let subject = new_subject()
send(subject, "Hello, Joe!")
pub external fn sleep(Int) -> Nil

Suspends the process calling this function for the specified number of milliseconds.

pub external fn sleep_forever() -> Nil

Suspends the process forever! This may be useful for suspending the main process in a Gleam program when it has no more work to do but we want other processes to continue to work.

pub fn start(running implementation: fn() -> a, linked link: Bool) -> Pid

Create a new Erlang process that runs concurrently to the creator. In other languages this might be called a fibre, a green thread, or a coroutine.

If linked is True then the created process is linked to the creator process. When a process terminates an exit signal is sent to all other processes that are linked to it, causing the process to either terminate or have to handle the signal.

More can be read about processes and links in the Erlang documentation.

pub fn subject_owner(subject: Subject(a)) -> Pid

Get the owner process for a Subject. This is the process that created the Subject and will receive messages sent with it.

pub fn try_call(subject: Subject(a), make_request: fn(Subject(b)) ->
    a, within timeout: Int) -> Result(b, CallError(b))

Send a message to a process and wait for a reply.

If the receiving process exits or does not reply within the allowed amount of time then an error is returned.