0Pricing
Go Academy · Lekcja

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

  1. Dlaczego istnieje context.Context
  2. WithCancel i WithTimeout
  3. WithDeadline i WithValue
  4. Kontekst w wywołaniach HTTP i baz danych
← Powrót do Go Academy