Ciclo de Vida do Processo
Nesta página
O Zolo oferece quatro pontos de extensão para o ciclo de vida de um processo CLI:
saída controlada com process.exit, limpeza LIFO com on shutdown, captura de
pânicos com on panic e interceptação de sinais com on signal.
Saída controlada
process.exit(code) encerra o processo com o código informado e ainda dispara
todos os ganchos on shutdown antes de sair — ao contrário de um abort abrupto:
O hook on shutdown reason é registrado antes do process.exit(0). Execute
localmente com DEMO_MODE=fail para ver a saída com código 1.
// Feature: controlled exit — `process.exit(code)`
// Syntax: `process.exit(0)` for success, `!= 0` for failure.
// When to use: a CLI script signaling a code to the shell; pre-flight
// checks that need to abort early. `on shutdown` hooks still run before
// the process exits.
use std::process
use std::env
on shutdown reason {
print("[shutdown] reason: {reason}")
}
let mode = env.get("DEMO_MODE") ?? "ok"
if mode == "fail" {
print("failure mode - exiting with 1")
process.exit(1)
}
print("success mode - exiting with 0")
process.exit(0)
print("unreachable")
// expected:
// success mode - exiting with 0
// [shutdown] reason: exit
Requer a CLI/host do Zolo — abra no playground ou rode localmente.
Múltiplos hooks de encerramento
Você pode declarar quantos blocos on shutdown quiser. Eles disparam em ordem
LIFO (o último declarado roda primeiro), o que facilita a composição de
camadas de limpeza independentes:
Três blocos on shutdown — o hook 3 roda antes do 2, que roda antes do 1.
O parâmetro reason é opcional: omiti-lo é válido.
// Feature: lifecycle — `on shutdown` (composes in LIFO order)
// Syntax: `on shutdown { ... }` or `on shutdown reason { ... }`
// When to use: clean up resources (close files, flush logs, drop
// connections) regardless of the exit path (normal, exit, panic, signal).
// Multiple blocks compose in LIFO order — the last one declared runs first.
on shutdown {
print("[hook 1] outermost cleanup (declared first, runs LAST)")
}
on shutdown reason {
print("[hook 2] exit reason: {reason}")
}
on shutdown {
print("[hook 3] innermost cleanup (declared last, runs FIRST)")
}
print("main work")
print("done")
// expected:
// main work
// done
// [hook 3] innermost cleanup (declared last, runs FIRST)
// [hook 2] exit reason: normal
// [hook 1] outermost cleanup (declared first, runs LAST)
Requer a CLI/host do Zolo — abra no playground ou rode localmente.
Captura de pânico
on panic e é o último recurso antes do encerramento por erro fatal: recebe a
mensagem de panic(...) e roda antes de on shutdown. Use para gravar logs de
diagnóstico ou métricas de falha:
O panic(...) está comentado para manter código de saída 0 no sandbox; leia os
comentários e descomente localmente para ver a sequência completa.
// Feature: lifecycle — `on panic` catches uncaught panics
// Syntax: `on panic e { ... }` receives the message; runs BEFORE
// `on shutdown` — last chance to log / dump diagnostics.
// When to use: catch crashes in production (telemetry, dump file),
// turn a panic into a structured log entry.
//
// NOTE: an uncaught panic exits the process with a non-zero status
// AFTER the `on panic` / `on shutdown` hooks fire. To keep this
// example green in test harnesses (which expect exit code 0), the
// `panic(...)` call below is left commented out and only documented.
on panic e {
print("[panic] caught: {e}")
}
on shutdown reason {
print("[shutdown] reason: {reason}")
}
print("before crash")
// panic("something went very wrong")
//
// expected (when the panic line is uncommented):
// before crash
// [panic] caught: something went very wrong
// [shutdown] reason: panic
// (process exits with non-zero status)
print("(panic skipped to keep exit code 0; see comment above)")
Requer a CLI/host do Zolo — abra no playground ou rode localmente.
Sinais do sistema operacional
on signal SIGINT { ... } registra um handler assíncrono para um sinal. Em
Windows somente SIGINT (Ctrl+C) e SIGTERM (Ctrl+Break) são entregues.
process.raise permite sintetizar o sinal em-processo para testes:
process.raise("SIGINT") entrega o sinal; process.sleep(50) aguarda a thread
de sinal drenar o evento antes que a execução principal prossiga.
// Feature: lifecycle — `on signal` for SIGINT / SIGTERM
// Syntax: `on signal SIGINT { ... }`. On Windows, only SIGINT (Ctrl+C)
// and SIGTERM (Ctrl+Break) are delivered.
// When to use: graceful shutdown — interrupt server loops, save
// state, close connections before dying.
use std::process
var fired = 0
on signal SIGINT {
fired = fired + 1
print("SIGINT received (time #{fired})")
}
on shutdown reason {
print("shutdown reason: {reason}")
}
// `process.raise` injects a synthetic signal — useful for testing
// without needing a shell to send Ctrl+C from outside.
print("raising SIGINT...")
process.raise("SIGINT")
// Give the lifecycle thread time to drain the signal.
process.sleep(50)
print("after sleep, fired={fired}")
print("done")
// expected:
// raising SIGINT...
// SIGINT received (time #1)
// after sleep, fired=1
// done
// shutdown reason: normal
Requer a CLI/host do Zolo — abra no playground ou rode localmente.
Desafio
Adicione um segundo on signal SIGINT que imprime "handler 2" e verifique que
ambos disparam na ordem de declaração quando process.raise("SIGINT") é chamado.
Veja também