Zrozumienie kontekstów w Go

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ść.

kontekst według wyniku kodu wartości

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

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *