Elixir process - Explain more - Part 2
Author: Manh Vu
Published: 2024-07-07

Intro

Elixir process is weird & hard to fully understand.

Every single line of code is run in a process so understand it help us work good with Elixir.

Process is a way of Elixir (backed by Erlang VM) support concurrent & fault tolerance.

Process is a isolated island

Code in a process cannot access to data from outside like global variable (Elixir doesn’t have) or data in other process.

Other process can communicate to a process for transfer data by message way (send/receive do). It looks like react model. Each process has a pid to other process can send message and a mailbox to store message for receive do can process message.

communicate between processes

Process has a pid for identify in local (one node) & remote node (cluster). It can have a name (atom) and we can register name by Process.register/2 function. Remember we can use process name to send message instead pid.

mailbox

Remember if we send a message to a process that no longer exists by pid message will be ignore by system and by process name system will return an error.

Note:

  • All messages go to a process will placed in mailbox and it can make of OOM error if process cannot consume fast enough.
  • Message with large data is make slowly and memory grow fast.

Way to spawn a process

We have two way to spawn process. One is use spawn functions (included Task). One is use supervisor by declare it in supervisor (or add child dynamically) and supervisor will start process.

Spawn flow: spawn process (process 1 spawn process 2)

Supervisor flow: supervisor (Supervisor create child processes - child 1 & child 2)

How process runs

We have a basic info about Elixir process but we still don’t how it run in system (Erlang VM - ErlVM).

Our Elixir code will compile to BEAM code then ErlVM will execute it. As we know every single line of code is run in a process, we have a schedulers to manage scheduler. Each scheduler has a run queue for hold processes. Number of schedulers has default equal to number of cpu core in system and can be config at start time. ErlVM provides mechanism to rebalance number of processes between run queue. We will go to detail of this in another post.

Basic diagram of schedulers:

Schedulers

Scheduler will pick another process in queue to run if current process has reach to max number of reductions. Another thing we need to know is scheduler using preemptive scheduling then it’s provided quite equal cpu resource for processes (of course we still have a priority queue for specific system task).

Running queue

Another thing we need to now is GC (garbage collector) of ErlVM. Each process has a heap memory and & a GC to clean up memory in its heap. ErlVM also have a global heap & global GC. This point is different to other languages like Java, Golang (using global GC). GC run on resource of a scheduler runner then it doesn’t affect to other processes (no stop the world like Golang/Java). This make ErlVM support soft realtime!

Advanced feature of process

Elixir (based Erlang/OTP) is uniqued system and it has some powerful features other languages doesn’t have. Ex: link between process, monitor process. I have explain a little of bit in other post then we come back later with more use cases for that.

(I will update more detail in the future)