𝗚𝗼 𝗖𝗼𝗻𝘁𝗲𝘅𝘁 𝗣𝗮𝗰𝗸𝗮𝗴𝗲
La maggior parte degli sviluppatori Go utilizza context.Context senza comprenderlo appieno. Lo trovi negli handler HTTP, nelle chiamate al database e nei metodi SDK. Molti principianti passano context.Background() ovunque.
Questo errore causa problemi. Una funzione Lambda potrebbe rimanere appesa oltre il proprio timeout. Una query al database potrebbe continuare a girare dopo che un utente si è disconnesso.
Il Context ti permette di inviare segnali di cancellazione e scadenze (deadlines) attraverso il tuo codice. Ti aiuta a rispondere a tre domande:
• Questa operazione deve continuare a girare? • Quando deve terminare questa operazione? • Quali dati della richiesta scorrono con questa chiamata?
L'interfaccia Context ha quattro metodi:
Deadline(): Restituisce quando il context verrà cancellato.Done(): Restituisce un canale che si chiude quando il context viene cancellato. Usalo nelle istruzioniselectper interrompere il lavoro.Err(): Restituisce il motivo per cui il context si è fermato (DeadlineExceededoCanceled).Value(): Recupera dati relativi allo scope della richiesta, come un Trace ID.
Il Context funziona come un albero. Si parte da un context genitore e si creano dei figli.
Context Radice:
context.Background(): Usalo all'inizio del programma.context.TODO(): Usalo come segnaposto durante il refactoring.
Context Figli:
context.WithCancel(): Ti permette di interrompere il lavoro manualmente.context.WithTimeout(): Interrompe il lavoro dopo una durata specifica.context.WithDeadline(): Interrompe il lavoro a un orario specifico.context.WithValue(): Passa metadati come gli User ID.
Regola Cruciale: Chiama sempre la funzione cancel. Usa defer cancel() immediatamente dopo aver creato un context figlio. Se ometti questo passaggio, creerai memory leak.
Best Practice:
- Passa il context come primo argomento alle funzioni.
- Non memorizzare il context nelle struct.
- Usa
context.WithValuesolo per i metadati, non per le dipendenze come i client del database. - Controlla
ctx.Err()all'interno di loop lunghi per uscire anticipatamente. - Usa tipi personalizzati per le chiavi del context per evitare collisioni.
Quando un context genitore viene cancellato, tutti i suoi figli vengono cancellati automaticamente. Questo rende facile interrompere un'intera catena di operazioni in tutto il sistema.