CodeBlanks Logo Icon CodeBlanks

WithTimeout

WithTimeout ile zaman sınırlı context öğrenirsin.

WithTimeout

context.WithTimeout(ust, sure) verilen süre dolunca kendiliğinden iptal olan bir context oluşturur. Ağ istekleri ve veritabanı sorgularında sonsuz beklemeyi önler:

ctx, cancel := context.WithTimeout(r.Context(), 2*time.Second)
defer cancel()

req, _ := http.NewRequestWithContext(ctx, "GET", url, nil)
resp, err := http.DefaultClient.Do(req)
// 2 saniyede yanıt yoksa err: context deadline exceeded

Neden defer cancel yine gerekli?

Süre dolunca context kendiliğinden iptal olsa da iş erken biterse içerideki zamanlayıcı süre dolana kadar bellekte kalır. defer cancel() zamanlayıcıyı hemen durdurur. Hatanın zaman aşımından mı kaynaklandığını anlamak için errors.Is(err, context.DeadlineExceeded) kullanılır.

Uygulama Yavaş işlem

yavas(ctx context.Context) error yaz: select ile time.After(100*time.Millisecond) veya ctx.Done() beklesin, iptalde ctx.Err() döndürsün. 10 ms zaman aşımıyla çağır ve hatanın DeadlineExceeded olduğunu errors.Is ile yazdır.

Başlangıç kodu

main.go
package main

import (
    "context"
    "errors"
    "fmt"
    "time"
)

func main() {
    // buraya yaz
}

Örnek çözüm

main.go
package main

import (
    "context"
    "errors"
    "fmt"
    "time"
)

func yavas(ctx context.Context) error {
    select {
    case <-time.After(100 * time.Millisecond):
        return nil
    case <-ctx.Done():
        return ctx.Err()
    }
}

func main() {
    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Millisecond)
    defer cancel()
    err := yavas(ctx)
    fmt.Println(errors.Is(err, context.DeadlineExceeded))
}

Beklenen çıktı

true

Soru ve cevaplar

Dersin sorularını cevaplarıyla birlikte inceleyebilirsin. Kendini denemek istersen dersi interaktif olarak çöz.

1 Üst context 1 saniyede bitiyorsa <code>WithTimeout(ust, 5*time.Second)</code> ne zaman iptal olur?

  • 1 saniyede (üstle birlikte) Doğru cevap
  • 5 saniyede
  • 6 saniyede
  • Hiçbir zaman

Açıklama: Alt context üstünden uzun yaşayamaz; geçerli son tarih ikisinden erken olanıdır.

2 Zaman aşımı hatası

Soru
if errors.Is(err, context.____) {
    log.Println("zaman aşımı")
}
Cevap
if errors.Is(err, context.DeadlineExceeded) {
    log.Println("zaman aşımı")
}

Açıklama: DeadlineExceeded, süre dolduğu için iptal edilen context'in hatasıdır.

3 Hata ve neden

Kavram Anlamı
context.Canceled cancel() çağrıldı
context.DeadlineExceeded Süre doldu
NewRequestWithContext İsteğe ctx bağlar
defer cancel() Zamanlayıcıyı durdurur

Orta seviye bölümündeki tüm dersler