Sobes.tech
Middle

Go dilinde bağlamlar nasıl yapılandırılmıştır?

sobes.tech yapay zeka

AI'dan gelen yanıt

Go dilinde (context.Context) bağlam, API sınırları arasında zaman aşımı, iptal ve diğer verilerin iletimi için kullanılır. Ağaç yapısı gösterir: Her bağlam, kök (context.Background() veya context.TODO()) hariç, başka bir bağlamın çocuğudur.

context.Context arayüzünün temel yöntemleri:

  • Deadline() (deadline time.Time, ok bool): Bağlamın zaman aşımını döndürür.
  • Done() <-chan struct{}: Bağlam iptal edildiğinde kapanan kanalı döndürür.
  • Err() error: Bağlamın iptaline neden olan hatayı döndürür.
  • Value(key any) any: Bağlamdaki anahtarla ilişkili değeri döndürür.

context paketinin fonksiyonlarıyla oluşturulur:

  • context.Background(): Ana süreç için temel olan boş kök bağlam.
  • context.TODO(): Hangi bağlamın kullanılacağı bilinmediğinde yer tutucu olarak kullanılır.
  • context.WithCancel(parent Context): Çocuk bağlam ve iptal fonksiyonu oluşturur.
  • context.WithDeadline(parent Context, d time.Time): Zaman aşımı ile çocuk bağlam oluşturur.
  • context.WithTimeout(parent Context, timeout time.Duration): Süre aşımı ile çocuk bağlam oluşturur.
  • context.WithValue(parent Context, key, val any): Değer ile çocuk bağlam oluşturur.

Context'in temel uygulamaları:

  • emptyCtx: Temel, iptal edilemez ve değer içermez. Background ve TODO kullanılır.
  • cancelCtx: İptal desteği sağlar. Temel bağlam ve iptal kanalı içerir.
  • timerCtx: Zaman aşımı veya süre sınırı destekler. cancelCtx ve zamanlayıcı içerir.
  • valueCtx: Değer iletimi sağlar. Temel bağlam ve anahtar-değer çifti içerir.

Üst bağlam iptal edildiğinde, tüm alt bağlamlar otomatik olarak iptal edilir. Bu, iptal sinyallerinin veya zaman aşımlarının zincir boyunca yayılmasını sağlar.

context.WithCancel kullanım örneği:

package main

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

func main() {
	// Kök bağlam ve iptal fonksiyonu oluştur
	ctx, cancel := context.WithCancel(context.Background())
	defer cancel() // main çıkışında iptali garanti eder

	go func() {
		select {
		case <-ctx.Done(): // Bağlam iptalini bekle
			fmt.Println("Görev iptal edildi:", ctx.Err())
			return
		case <-time.After(5 * time.Second): // Veya 5 saniye sonra
			fmt.Println("Görev tamamlandı")
		}
	}()

	// Başka bir yerden bağlamı iptal et
	time.Sleep(1 * time.Second)
	fmt.Println("Bağlam iptali...")
	cancel()

	// İptali işleyen goroutine'e zaman tanı
	time.Sleep(100 * time.Millisecond)
}

context.WithValue kullanımı örneği:

package main

import (
	"context"
	"fmt"
)

type userIDKey string

func processRequest(ctx context.Context) {
	if userID, ok := ctx.Value(userIDKey("UserID")).(string); ok {
		fmt.Println("Kullanıcı ID'si için istek işleniyor:", userID)
	} else {
		fmt.Println("Bağlamda kullanıcı ID'si bulunamadı")
	}
}

func main() {
	ctx := context.WithValue(context.Background(), userIDKey("UserID"), "12345")
	processRequest(ctx)
}

Bağlamlar, çoklu iş parçacığı ortamında güvenlidir ve değiştirilemezler, bu da eşzamanlı kodlar için önemlidir. İşlevlerin ham parametrelerini iletmek yerine, işlemin yürütülmesine etki eden meta bilgileri iletmek için tasarlanmıştır.