Do you want to pick up from where you left of?
Take me there

OTP Supervisors

Supervisor adalah proses khusus yang memiliki satu peran: memonitor proses lain. Supervisor ini memungkinkan kita membuat aplikasi yang toleran-kegagalan (fault-tolerant) dengan secara otomatis menjalankan ulang proses anak (child process) jika proses anak itu fail (mengalami kegagalan).

Konfigurasi

Inti Supervisor adalah fungsi Supervisor.start_link/2. Di samping menjalankan supervisor kita dan anak-anaknya, fungsi ini juga memungkinkan kita mendefinisikan strategi yang digunakan supervisor kita untuk mengatur proses-proses anak.

Proses-proses anak didefinisikan menggunakan sebuah list dan fungsi worker/3 yang kita import dari Supervisor.Spec. Fungsi worker/3 ini menerima sebuah modul, argumen, dan sekumpulang opsi. Di dalamnya worker/3 memanggil start_link/3 dengan argumen-argumen kita dalam inisialisasi.

Menggunakan SimpleQueue dari pelajaran OTP Concurrency mari kita mulai:

import Supervisor.Spec

children = [
  worker(SimpleQueue, [], name: SimpleQueue)
]

{:ok, pid} = Supervisor.start_link(children, strategy: :one_for_one)

Jika proses kita crash atau diterminasi Supervisor kita akan secara otomatis menjalankan ulang seakan tidak ada yang terjadi.

Strategi

Saat ini ada empat strategi penjalanan ulang yang tersedia untuk supervisor:

Nesting

Di samping proses pekerja (worker process), kita juga bisa mensupervisi supervisor lain untuk membuat sebuah pohon supervisor (supervisor tree). Satu-satunya perbedaan adalah menggantikan worker/3 dengan supervisor/3:

import Supervisor.Spec

children = [
  supervisor(ExampleApp.ConnectionSupervisor, [[name: ExampleApp.ConnectionSupervisor]]),
  worker(SimpleQueue, [[], [name: SimpleQueue]])
]

{:ok, pid} = Supervisor.start_link(children, strategy: :one_for_one)

Supervisor untuk Task

Task punya Supervisornya sendiri, Task.Supervisor. Didesain untuk task yang dibuat secara dinamis, supervisor ini menggunakan :simple_one_for_one di dalamnya.

Setup

Menggunakan Task.Supervisor tidak beda dengan supervisor lain:

import Supervisor.Spec

children = [
  supervisor(Task.Supervisor, [[name: ExampleApp.TaskSupervisor]])
]

{:ok, pid} = Supervisor.start_link(children, strategy: :one_for_one)

Task yang Disupervisi

Setelah supervisor dijalankan kita bisa menggunakan fungsi start_child/2 untuk membuat task yang disupervisi:

{:ok, pid} = Task.Supervisor.start_child(ExampleApp.TaskSupervisor, fn -> background_work end)

Jika task kita crash sebelum waktunya, task itu akan dijalankan ulang (restart) untuk kita. Ini khususnya bisa berguna ketika bekerja dengan koneksi yang datang atau memproses pekerjaan di belakang layar (background work).

Caught a mistake or want to contribute to the lesson? Edit this lesson on GitHub!