WithDeadline i WithValue
Bezwzględne terminy i przekazywanie wartości związanych z żądaniem
WithDeadline i WithValue to bezpłatna lekcja Go Academy na CoddyKit. To lekcja 3 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Go Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Go Academy zawiera 4 lekcji w sumie.
context.WithDeadline
WithDeadline tworzy kontekst, który anuluje się o określonej godzinie. Jeśli kontekst nadrzędny ma wcześniejszy termin, pierwszeństwo ma termin kontekstu nadrzędnego.
deadline := time.Now().Add(10 * time.Second)
ctx, cancel := context.WithDeadline(parent, deadline)
defer cancel()WithTimeout a WithDeadline
WithTimeout(parent, d) jest równoważne WithDeadline(parent, time.Now().Add(d)). Należy użyć WithDeadline, gdy mają Państwo bezwzględny termin wygaśnięcia, np. pochodzący z nagłówka przychodzącego RPC.
Odczytywanie deadline'u
Deadline dowolnego kontekstu można sprawdzić za pomocą ctx.Deadline(). Wartość logiczna informuje, czy deadline istnieje.
if deadline, ok := ctx.Deadline(); ok {
fmt.Println("expires at:", deadline)
}context.WithValue
WithValue dołącza parę klucz-wartość do kontekstu. Kod znajdujący się dalej pobiera ją za pomocą ctx.Value(key).
type ctxKey string
const userKey ctxKey = "user"
ctx := context.WithValue(parent, userKey, currentUser)
func getUser(ctx context.Context) *User {
u, _ := ctx.Value(userKey).(*User)
return u
}Zapobieganie kolizjom kluczy
Należy używać nieeksportowanego typu specyficznego dla pakietu jako klucza, aby zapobiegać kolizjom między pakietami. Nie należy bezpośrednio używać typów wbudowanych (string, int) jako kluczy kontekstu.
// Bad: string key can collide
ctx = context.WithValue(ctx, "user", u)
// Good: package-scoped type
type userKeyType struct{}
ctx = context.WithValue(ctx, userKeyType{}, u)Co przechowywać w context
Należy przechowywać wyłącznie wartości związane z żądaniem, które przekraczają granice API: identyfikatory śledzenia, tokeny uwierzytelniania i identyfikatory żądań. Nie należy przechowywać opcjonalnych argumentów funkcji ani zmiennego stanu.
Wydajność WithValue
ctx.Value wykonuje wyszukiwanie liniowe w łańcuchu kontekstów. Należy unikać przechowywania wielu wartości w jednym kontekście; wiele wartości lepiej grupować w jednej strukturze.
type RequestMeta struct {
UserID int
TraceID string
}
type metaKey struct{}
ctx = context.WithValue(ctx, metaKey{}, RequestMeta{...})Przekazywanie wartości przez middleware
Middleware HTTP to standardowe miejsce do dołączania metadanych żądania do kontekstu i pobierania ich w handlerach:
func Auth(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
user := authenticate(r)
ctx := context.WithValue(r.Context(), userKey, user)
next.ServeHTTP(w, r.WithContext(ctx))
})
}r.WithContext
Kontekst żądania HTTP można zastąpić za pomocą r.WithContext(ctx). Tworzy to płytką kopię żądania z nowym kontekstem, pozostawiając oryginał bez zmian.
Propagowanie deadline'u
Gdy bramka ustawi deadline w kontekście i przekaże żądanie dalej, wszystkie usługi, które przyjmują ten kontekst, automatycznie respektują deadline bez jawnej logiki limitu czasu.
Łańcuch kontekstów
Każde WithValue, WithCancel i WithTimeout opakowuje kontekst nadrzędny w nowy węzeł. ctx.Value przechodzi wzdłuż łańcucha, aż znajdzie klucz lub dotrze do kontekstu głównego, który zwraca nil.
Szybkie sprawdzenie
Dlaczego klucze kontekstu powinny być nieeksportowanymi typami specyficznymi dla pakietu?
Podsumowanie: WithDeadline i WithValue
Najważniejsze informacje:
- WithDeadline anuluje kontekst o bezwzględnym czasie; WithTimeout korzysta z czasu względnego
ctx.Deadline()odczytuje deadline- WithValue służy do metadanych związanych z żądaniem; należy używać typowanych, nieeksportowanych kluczy
- Wiele wartości należy grupować w strukturze, aby zmniejszyć głębokość łańcucha
Często zadawane pytania
Czy lekcja „WithDeadline i WithValue” jest bezpłatna?
Tak — pełny tekst „WithDeadline i WithValue” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Go Academy, przejdź na CoddyKit PRO. Kurs Go Academy zawiera 4 lekcji w sumie.
Co nauczysz się w „WithDeadline i WithValue”?
Bezwzględne terminy i przekazywanie wartości związanych z żądaniem Ćwiczysz Go Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć Go Academy?
Nie wymagamy żadnego doświadczenia. Go Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 3 z 4.
Ile czasu zajmuje lekcja „WithDeadline i WithValue”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji Go Academy?
Tak. Każda lekcja Go Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Dlaczego istnieje context.Context
- WithCancel i WithTimeout
- WithDeadline i WithValue
- Kontekst w wywołaniach HTTP i baz danych