Junior
Čo je to kontext v Go?
sobes.tech AI
Odpoveď od AI
V kontexte (context.Context) v jazyku Go je objekt, ktorý nesie dátum, signál zrušenia (cancellation signal) a údaje, špecifické pre požiadavku. Používa sa na riadenie životného cyklu gorutín a prenos informácií medzi nimi počas vykonávania jednej požiadavky/operácie.
Hlavné vlastnosti:
- Bezpečný pre vlákna: Môže byť bezpečne prenesený medzi gorutínami.
- Imutabilný: Po vytvorení sa
Contextnedá zmeniť. Derivátne kontexty sa vytvárajú na základe rodičovského. - Hierarchický: Kontexte tvoria strom s koreňom (
context.Background()alebocontext.TODO()). Zrušenie rodičovského kontextu spôsobí zrušenie všetkých dcér.
Hlavné funkcie balíka context:
context.Background(): Prázdny kontext, zvyčajne sa používa v hlavnej funkcii, pri vrchných požiadavkách alebo pri testovaní. Nikdy nie je zrušený.context.TODO(): Svojím spôsobom prázdny kontext. Používa sa ako záložný, keď nie je známe, ktorý kontext použiť, alebo ak funkčnosť kontextu ešte nie je implementovaná.context.WithCancel(parent Context): Vráti nový dcérsky kontext a funkciu na zrušenie. Volaním funkcie na zrušenie, tento kontext a všetky jeho dcérske sa zrušia.context.WithDeadline(parent Context, deadline time.Time): Vráti dcérsky kontext, ktorý sa automaticky zruší, keď nastane uvedený čas. Taktiež vráti funkciu na manuálne zrušenie.context.WithTimeout(parent Context, timeout time.Duration): To isté akoWithDeadline, ale s určením trvania.context.WithValue(parent Context, key, val interface{}): Vráti dcérsky kontext s priradenou hodnotou kľúča.
Použitie:
- Zrušenie operácií: Napríklad, timeout HTTP požiadavky alebo prerušenie dlhodobej operácie.
- Prenos dát: Napríklad, ID požiadavky na logovanie, autentifikačné informácie.
Príklad použitia context.WithTimeout:
package main
import (
"context"
"fmt"
"time"
)
func longRunningOperation(ctx context.Context, resultChan chan string) {
select {
case <-time.After(3 * time.Second):
// Operácia úspešne dokončená
resultChan <- "Operation completed"
case <-ctx.Done():
// Kontext bol zrušený
err := ctx.Err() // Získavame dôvod zrušenia
resultChan <- fmt.Sprintf("Operation cancelled: %v", err)
}
}
func main() {
// Vytvorenie kontextu s časovým limitom 2 sekundy
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel() // Zabezpečíme volanie zrušovacej funkcie
resultChan := make(chan string, 1)
go longRunningOperation(ctx, resultChan)
// Čakáme na výsledok alebo zrušenie
select {
case res := <-resultChan:
fmt.Println(res)
case <-ctx.Done():
fmt.Printf("Main context done: %v\n", ctx.Err())
}
// Počkáme trochu, aby mohol skončiť, ak bola zrušená
time.Sleep(1 * time.Second)
}
V tomto príklade longRunningOperation kontroluje kontext na zrušenie. Ak časový limit hlavného kontextu (2 sekundy) vyprší skôr, než sa dokončí sama operácia (3 sekundy), gorutina dostane signál zrušenia cez ctx.Done() a ukončí sa.