-
Notifications
You must be signed in to change notification settings - Fork 0
/
process_waiter.gleam
33 lines (30 loc) · 940 Bytes
/
process_waiter.gleam
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import gleam/erlang/process.{type Pid, type ProcessMonitor, type Selector}
import gleam/dict.{type Dict}
import gleam/list
/// Wait for a list of processes to exit.
///
pub fn await_forever(pids: List(Pid)) -> Nil {
let monitors =
pids
|> list.map(fn(pid) { #(pid, process.monitor_process(pid)) })
|> dict.from_list
let selector = selector_for_monitors(monitors)
await_forever_loop(monitors, selector)
}
fn await_forever_loop(
pids: Dict(Pid, ProcessMonitor),
selector: Selector(Pid),
) -> Nil {
let pid = process.select_forever(selector)
let pids = dict.delete(pids, pid)
case dict.size(pids) {
0 -> Nil
_ -> await_forever_loop(pids, selector)
}
}
fn selector_for_monitors(monitors: Dict(Pid, ProcessMonitor)) -> Selector(Pid) {
dict.values(monitors)
|> list.fold(process.new_selector(), fn(selector, monitor) {
process.selecting_process_down(selector, monitor, fn(msg) { msg.pid })
})
}