Zrozumienie kontekstów w Go
Kontekst jest jedną z krytycznych funkcji Go, która umożliwia współbieżność. W Go „kontekst” odnosi się do pakietu, który zapewnia funkcjonalność dla wartości o zasięgu żądania i sygnałów anulowania poza granicami API.
Pakiet kontekstowy działa jednocześnie z modelem współbieżności Go, opartym na koncepcji gorutyn. Goroutines to lekkie wątki wykonawcze, które można efektywnie tworzyć i nimi zarządzać, ułatwiając tworzenie współbieżnych programów w Go.
Pakiet kontekstowy
Pakiet kontekstowy zapewnia funkcjonalność do anulowania długotrwałych funkcji lub całych łańcuchów wywołań. Pakiet pomaga również w przechowywaniu wartości o zasięgu żądania w celu uzyskania dostępu w dowolnym miejscu w łańcuchu wywołań. Ta funkcja jest przydatna podczas pracy z interfejsami API lub mikrousługami, w których żądania mogą obejmować wiele wywołań funkcji i chcesz je anulować lub dołączyć do nich określone wartości.
Oto jak możesz zaimportować pakiet kontekstowy do swoich programów Go.
import "context"
Funkcje kontekstu przyjmują typ struktury kontekstu pakietu kontekstu . Konwencjonalnie powinieneś użyć ctx jako nazwy zmiennej instancji.
func operations(ctx context.Context) {
}
Funkcje mogą zwracać typ struktury kontekstu dla innych funkcji i operacji.
func operations(ctx context.Context) context.Context {
}
Możesz utworzyć nowy kontekst za pomocą funkcji TODO pakietu context. Funkcja TODO tworzy nowy kontekst z wartością context.Done() , kanał, który zostanie zamknięty po anulowaniu kontekstu. Powinieneś użyć go jako symbolu zastępczego, gdy potrzebujesz kontekstu, ale żadne konteksty nadrzędne nie są odpowiednie.
import "context"
func main() {
ctx: = context.TODO()
}
Alternatywnie funkcja tła tworzy nowy kontekst bez wartości i pusty kanał Gotowe.
ctx: = context.Background()
Powinieneś użyć funkcji Background jako korzenia drzewa kontekstu.
Kontekst z wartościami
Pakiet kontekstu zapewnia funkcjonalność propagowania wartości i sygnałów anulowania. Możesz użyć tych wartości, aby uzyskać informacje od danych o zakresie żądania do sygnałów anulowania i terminów.
Pakiet kontekstowy umożliwia również tworzenie kontekstu potomnego odziedziczonego z kontekstów nadrzędnych, co pozwala na efektywną obsługę wartości i sygnałów anulowania w całym programie, ponieważ kontekst można przekazywać przez wiele funkcji.
Oto przykład przekazywania kontekstu przez funkcje za pomocą pakietu context.
import (
"context"
)
func valuableContext(ctx context.Context) context.Context {
return context.WithValue(ctx, "pass-key", "hfouneqcelkwfu")
}
func receiveContextData(ctx context.Context) any {
passKey: = ctx.Value("pass-key")
return passKey
}
FunkcjavalueContext przyjmuje instancję kontekstu i zwraca instancję kontekstu dla następującej funkcji . Instancja kontekstu jest wartością utworzoną za pomocą metody WithValue . Metoda WithValue pobiera instancję kontekstu z funkcji i pary klucz-wartość.
Aby pobrać dane z kontekstu, musisz utworzyć nowy kontekst za pomocą funkcji TODO lub Background i przekazać kontekst do funkcji (w tym przypadku wartościowyKontekst) i otrzymać kontekst za pomocą funkcji receiveContextData .
func main() {
ctx: = context.Background()
ctx = valuableContext(ctx)
fmt.Println(receiveContextData(ctx))
}
Zmienna ctx jest instancją kontekstu z funkcji Background. FunkcjavalueContext przyjmuje zmienną ctx i zwraca kontekst z wartością, którą przyjmuje funkcja receiveContextData i zwraca wartość z pary klucz-wartość.
Limity czasu i terminy kontekstu
Pakiet kontekstowy zapewnia funkcjonalność do ustawiania limitów czasu i terminów w operacjach. Ustawianie limitów czasu i terminów jest przydatne w przypadku operacji, które muszą nadrobić zaległości.
Limity czasu to czas trwania operacji. Możesz ustawić limit czasu operacji na 4 sekundy; po tym kontekst anuluje żądanie.
Z drugiej strony termin definiuje bezwzględny punkt, w którym operacja powinna zostać anulowana.
Możesz użyć metody WithTimeout , aby ustawić limit czasu kontekstu. Oto jak ustawić 2-sekundowy limit czasu.
func main() {
ctx, cancel: = context.WithTimeout(context.Background(), 2 * time.Second)
defer cancel()
// some operation
}
Funkcja main tworzy kontekst z limitem czasu wynoszącym dwie sekundy. Funkcja WithTimeout zwraca funkcję anulowania, którą można odroczyć do anulowania przy wyjściu z funkcji main.
Możesz zadeklarować terminy za pomocą metody WithDeadline . Metoda WithDeadline przyjmuje instancję kontekstu i termin ostateczny.
func doSomething(ctx context.Context) {
deadlineTime: = time.Now().Add(1500 * time.Millisecond)
ctx, ctxCancel: = context.WithDeadline(ctx, deadlineTime)
defer ctxCancel()
// some operation
ctxCancel()
}
Funkcja doSomething przyjmuje kontekst, a zmienna deadlineTime to czas przed ostatecznym terminem kontekstu . Zmienna ctx to kontekst z terminem.
Zmienna ctxCancel anuluje kontekst, gdy przekroczy on termin.
Najlepsze praktyki dotyczące używania kontekstów w Go
Unikaj używania kontekstów jako zmiennych globalnych. Używanie kontekstów jako zmiennych globalnych może prowadzić do nieoczekiwanych zachowań kodu i trudnych do wyśledzenia błędów, a także oszczędnie używać kontekstu, aby zmniejszyć złożoność kodu.
Wreszcie, używaj kontekstów jako sygnałów, a nie gwarancji. Anulowanie kontekstu nie gwarantuje, że wszystkie goroutines przestaną działać; to tylko sygnał, a gorutyny są niezależne od kontekstów.
Dodaj komentarz