Current section
Files
Jump to
Current section
Files
src/process/supervisor/set_supervisor.gleam
// Other Possible name: Fleet Clone, Copy, Replica, Homogenious
import gleam/list
import process/process
import process/process.{From, Pid, BarePid, ExitReason, Normal, Infinity, Milliseconds, TrapExit}
import midas_utils
pub type Messages(m) {
StartChild(From(Pid(m)))
WhichChildren(From(List(Pid(m))))
EXIT(BarePid, ExitReason)
}
fn pop(haystack, predicate, done) {
case haystack {
[] -> tuple(Error(Nil), list.reverse(done))
[x, ..rest] -> case predicate(x) {
True -> tuple(Ok(x), list.append(list.reverse(done), rest))
False -> pop(rest, predicate, [x, ..done])
}
}
}
fn loop(receive, start_child, children) {
case receive(Infinity) {
Ok(StartChild(from)) -> {
let child = start_child()
let children = [child, ..children]
process.reply(from, child)
loop(receive, start_child, children)
}
Ok(WhichChildren(from)) -> {
process.reply(from, list.reverse(children))
loop(receive, start_child, children)
}
Ok(EXIT(down_pid, _)) -> {
let predicate = fn(pid) { process.bare(pid) == down_pid }
let tuple(_found, children) = pop(children, predicate, [])
loop(receive, start_child, children)
}
}
}
fn init(receive, start_child) {
process.process_flag(TrapExit(True))
loop(receive, start_child, [])
}
pub fn spawn_link(start_child: fn() -> Pid(a)) -> Pid(Messages(a)) {
process.spawn_link(init(_, start_child))
}
pub fn start_child(supervisor: Pid(Messages(m))) {
process.call(supervisor, StartChild(_), Milliseconds(5000))
}
pub fn which_children(supervisor) {
process.call(supervisor, WhichChildren(_), Milliseconds(5000))
}