Junior
Ce este contextul în Go?
sobes.tech AI
Răspuns de la AI
Contextul (context.Context) în Go este un obiect care transportă termenul limită, semnalul de anulare și date specifice solicitării. Este utilizat pentru gestionarea ciclului de viață al goroutine-urilor și pentru transmiterea informațiilor între ele în timpul executării unei solicitări/operațiuni.
Caracteristici principale:
- Sigur pentru concurență: Poate fi transferat în siguranță între goroutine-uri.
- Imutabil: Odată creat, un
Contextnu poate fi schimbat. Contextele derivate sunt create pe baza părintelui. - ** ierarhic**: Contextele formează un copac cu rădăcină (
context.Background()saucontext.TODO()). Anularea contextului părinte duce la anularea tuturor copiilor săi.
Funcții principale ale pachetului context:
context.Background(): Context gol, utilizat de obicei în funcția main, în solicitări de nivel înalt sau în teste. Nu este niciodată anulat.context.TODO(): De asemenea, un context gol. Este utilizat ca un înlocuitor atunci când nu se știe ce context să se folosească sau dacă funcționalitatea contextului nu a fost încă implementată.context.WithCancel(parent Context): Returnează un nou context copil și o funcție de anulare. Apelarea funcției de anulare anulează acest context și toate contextelor sale copil.context.WithDeadline(parent Context, deadline time.Time): Returnează un context copil care se anulează automat când timpul specificat este atins. De asemenea, returnează o funcție de anulare pentru anulare manuală.context.WithTimeout(parent Context, timeout time.Duration): La fel caWithDeadline, dar cu o durată specificată.context.WithValue(parent Context, key, val interface{}): Returnează un context copil cu o valoare atribuită unei chei.
Aplicații:
- Anularea operațiilor: De exemplu, timeout pentru o solicitare HTTP sau întreruperea unei operațiuni lungi.
- Transmiterea datelor: De exemplu, ID-ul solicitării pentru jurnalizare, informații de autentificare.
Exemplu de utilizare a context.WithTimeout:
package main
import (
"context"
"fmt"
"time"
)
func longRunningOperation(ctx context.Context, resultChan chan string) {
select {
case <-time.After(3 * time.Second):
// Operațiunea s-a finalizat cu succes
resultChan <- "Operațiune finalizată"
case <-ctx.Done():
// Contextul a fost anulat
err := ctx.Err() // Obține motivul anulării
resultChan <- fmt.Sprintf("Operațiune anulată: %v", err)
}
}
func main() {
// Crează un context cu timeout de 2 secunde
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel() // Asigură apelul funcției de anulare
resultChan := make(chan string, 1)
go longRunningOperation(ctx, resultChan)
// Așteaptă rezultatul sau anularea
select {
case res := <-resultChan:
fmt.Println(res)
case <-ctx.Done():
fmt.Printf("Contextul principal s-a terminat: %v\n", ctx.Err())
}
// Așteaptă puțin pentru ca goroutine-ul să se termine dacă a fost anulată
time.Sleep(1 * time.Second)
}
În acest exemplu, longRunningOperation verifică dacă contextul a fost anulat. Dacă timeout-ul contextului principal (2 secunde) expiră înainte ca operațiunea (3 secunde) să se finalizeze, goroutine-ul primește semnalul de anulare prin ctx.Done() și se termină.