Sobes.tech
Middle — Middle+

Qual è la sequenza di azioni necessaria per arrestare correttamente l'applicazione senza perdita di dati o errori?

sobes.tech AI

Risposta dell'AI

Per arrestare correttamente un'applicazione Go senza perdita di dati e con errori, si seguono generalmente i seguenti passaggi:

  1. Gestione dei segnali del sistema operativo — catturano i segnali di terminazione (SIGINT, SIGTERM) tramite un canale e signal.Notify.

  2. Avvio di uno shutdown graduale (graceful shutdown) — avviano una procedura di chiusura morbida, che interrompe l'accettazione di nuove richieste e permette alle richieste in corso di terminare.

  3. Annullamento del contesto — usano context.Context con cancellazione per trasmettere il segnale di stop a tutte le goroutine.

  4. Chiusura delle risorse — chiudono le connessioni aperte a database, file, connessioni di rete.

  5. Attesa che le goroutine terminino — tramite sync.WaitGroup o altri meccanismi, aspettano che tutte le operazioni siano completate.

Esempio di gestione del segnale e shutdown graduale:

import (
    "context"
    "os"
    "os/signal"
    "sync"
    "syscall"
    "time"
)

func main() {
    ctx, cancel := context.WithCancel(context.Background())
    var wg sync.WaitGroup

    // Avvio dell'applicazione
    wg.Add(1)
    go func() {
        defer wg.Done()
        runApp(ctx) // funzione con la logica principale
    }()

    // Gestione dei segnali
    sigs := make(chan os.Signal, 1)
    signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)

    <-sigs // aspetta il segnale
    cancel() // annulla il contesto, segnalando alle goroutine

    // Attende la conclusione
    done := make(chan struct{})
    go func() {
        wg.Wait()
        close(done)
    }()

    select {
    case <-done:
        // Tutto terminato
    case <-time.After(10 * time.Second):
        // Timeout di attesa
    }
}

Questo approccio aiuta a prevenire la perdita di dati e la chiusura impropria.