Sobes.tech
Middle — Middle+

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:

  1. Tratamento de sinais do sistema operativo — capturam sinais de término (SIGINT, SIGTERM) usando um canal e signal.Notify.

  2. 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.

  3. Cancelamento do contexto — usam context.Context com cancelamento para transmitir o sinal de paragem a todas as goroutines.

  4. Fecho de recursos — fecham conexões abertas a bases de dados, ficheiros, conexões de rede.

  5. Aguardar a conclusão das goroutines — usando sync.WaitGroup ou 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.