Qual é a sequência de ações necessária para parar corretamente a aplicação sem perder dados ou causar falhas?
sobes.tech IA
Resposta da IA
Para parar corretamente uma aplicação Go sem perda de dados e sem falhas, normalmente seguem-se os seguintes passos:
-
Tratamento de sinais do sistema operativo — capturam sinais de término (
SIGINT,SIGTERM) usando um canal esignal.Notify. -
Início do encerramento gracioso (graceful shutdown) — iniciam um procedimento de encerramento suave, que deixa de aceitar novas solicitações e permite que as atuais terminem.
-
Cancelamento do contexto — usam
context.Contextcom cancelamento para transmitir o sinal de paragem a todas as goroutines. -
Fecho de recursos — fecham conexões abertas a bases de dados, ficheiros, conexões de rede.
-
Aguardar a conclusão das goroutines — usando
sync.WaitGroupou outros mecanismos, aguardam até que todas as operações terminem.
Exemplo de tratamento de sinal e shutdown gracioso:
import (
"context"
"os"
"os/signal"
"sync"
"syscall"
"time"
)
func main() {
ctx, cancel := context.WithCancel(context.Background())
var wg sync.WaitGroup
// Início da aplicação
wg.Add(1)
go func() {
defer wg.Done()
runApp(ctx) // função com a lógica principal
}()
// Tratamento de sinais
sigs := make(chan os.Signal, 1)
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
<-sigs // espera pelo sinal
cancel() // cancela o contexto, sinalizando às goroutines
// Espera pela conclusão
done := make(chan struct{})
go func() {
wg.Wait()
close(done)
}()
select {
case <-done:
// Todos terminaram
case <-time.After(10 * time.Second):
// Timeout de espera
}
}
Este método ajuda a evitar perda de dados e encerramentos incorretos.