Resiliência
Objetivo: deixar processos falharem e reiniciarem com segurança (supervisão, links e monitors), tudo emergindo da estrutura do código (modelo BEAM, sem behaviours declarados à parte).
A morte é um valor de erro
Seção intitulada “A morte é um valor de erro”Quando um processo morre, a sequência é fixa: rodam os defers dele, libera-se o @mm dele, e
produz-se um error que descreve a morte (crash com motivo, ou saída limpa). Esse error é o
que chega a quem observa: é o error-as-value aplicado à morte de processo.
Monitor = o catch do spawn supervisionado
Seção intitulada “Monitor = o catch do spawn supervisionado”Você não precisa de um construto novo pra “ser avisado da morte sem morrer junto”: é o catch |e|
do spawn:
@supervisor(max_restarts: 3, window: 10s)spawn worker(data) catch |e| { // 'worker' morreu, EU (supervisor) não. 'e' é o motivo. Reajo sem propagar. log("worker caiu: {{e}}")}Como a morte é um error comum, você a discrimina com match |e|:
@supervisor(strategy: rest_for_one)spawn db(conn) match |e| { Normal => log("terminou o trabalho") Crashed(m) => restart() Timeout => escalate()}As três estratégias emergem da estrutura
Seção intitulada “As três estratégias emergem da estrutura”one_for_one: processos independentes, cada um com seucatch. Sem anotação, é o default (sem limite de restarts):
spawn worker_a(da) catch |e| { ... }spawn worker_b(db) catch |e| { ... } // se A cai, B não sabeone_for_all: umspawn-block, onde os processos vivem e morrem juntos. Se um cai, o coordinator mata os irmãos e reinicia o grupo:
spawn { indexer(docs) catch |e| { log(e) } notifier(subs) catch |e| { log(e) }} catch |e| { notify_ops("grupo crítico morreu: {{e}}") // o grupo inteiro se esgotou}rest_for_one: pipeline com ordem; o único que exige anotação (não é inferível):
@supervisor(strategy: rest_for_one)spawn { db_connection() // cai → reinicia os três db_writer() // cai → reinicia writer + reader db_reader() // cai → reinicia só reader} catch |e| { ... }Links e monitors, sem primitivas cruas
Seção intitulada “Links e monitors, sem primitivas cruas”A BEAM tem link/monitor/trap_exit como primitivas; Makoto não as expõe cruas. Acoplar
destino é a árvore (processos no mesmo spawn-block compartilham destino porque a estrutura diz
isso), e observar sem acoplar é o catch. Cascata de morte invisível some: a árvore de
supervisão é o código.
Retry é do caller
Seção intitulada “Retry é do caller”A função do processo é limpa, sem política de retry embutida; o @supervisor no call site decide
max_restarts/window. Quando esgota, o catch externo dispara, sem escalação automática.
Próximo: 08 · Memória