Sobes.tech
Junior

Go'da bağlam nedir?

sobes.tech yapay zeka

AI'dan gelen yanıt

Go'da (context.Context) bağlam, son tarih, iptal sinyali ve isteğe özel verileri taşıyan bir nesnedir. Bu, goroutine'lerin yaşam döngüsünü yönetmek ve bunlar arasında bilgi iletmek için kullanılır.

Ana özellikler:

  • Eşzamanlılık güvenli: Güvenle goroutine'ler arasında aktarılabilir.
  • Değiştirilemez: Bir kez oluşturulduktan sonra, bir Context değiştirilemez. Türev bağlamlar, ebeveynlerine dayanarak oluşturulur.
  • Hiyerarşik: Bağlamlar, kök (context.Background() veya context.TODO()) ile bir ağaç oluşturur. Ebeveyn bağlamın iptali, tüm çocukların iptaline yol açar.

context paketinin temel fonksiyonları:

  • context.Background() : Boş bağlam, genellikle ana fonksiyonda, üst düzey isteklerde veya testlerde kullanılır. Asla iptal edilmez.
  • context.TODO() : Ayrıca boş bir bağlamdır. Hangi bağlamın kullanılacağı bilinmediğinde veya bağlam fonksiyonelliği henüz uygulanmadığında yer tutucu olarak kullanılır.
  • context.WithCancel(parent Context) : Yeni bir çocuk bağlam ve iptal fonksiyonu döner. İptal fonksiyonu çağrıldığında, bu bağlam ve tüm alt bağlamlar iptal edilir.
  • context.WithDeadline(parent Context, deadline time.Time) : Belirtilen zamana ulaşıldığında otomatik olarak iptal edilen çocuk bağlamı döner. Ayrıca manuel iptal için bir fonksiyon da döner.
  • context.WithTimeout(parent Context, timeout time.Duration) : WithDeadline ile aynıdır, ancak süre belirtilir.
  • context.WithValue(parent Context, key, val interface{}) : Anahtar-değer çifti ile bir çocuk bağlamı döner.

Uygulamalar:

  • İşlemleri iptal etme: Örneğin, HTTP isteği zaman aşımı veya uzun süren bir işlemin kesilmesi.
  • Veri iletimi: Örneğin, günlük kaydı için istek kimliği veya kimlik doğrulama bilgileri.

context.WithTimeout kullanımına örnek:

package main

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

func longRunningOperation(ctx context.Context, resultChan chan string) {
	select {
	case <-time.After(3 * time.Second):
		// İşlem başarıyla tamamlandı
		resultChan <- "İşlem tamamlandı"
	case <-ctx.Done():
		// Bağlam iptal edildi
		err := ctx.Err() // İptal nedenini al
		resultChan <- fmt.Sprintf("İşlem iptal edildi: %v", err)
	}
}

func main() {
	// 2 saniyelik zaman aşımı ile bağlam oluştur
	ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
	defer cancel() // İptal çağrısını garanti altına al

	resultChan := make(chan string, 1)

	go longRunningOperation(ctx, resultChan)

	// Sonuç veya iptal bekle
	select {
	case res := <-resultChan:
		fmt.Println(res)
	case <-ctx.Done():
		fmt.Printf("Ana bağlam tamamlandı: %v\n", ctx.Err())
	}

	// İptal edilirse, goroutine'in bitmesini sağlamak için biraz bekle
	time.Sleep(1 * time.Second)
}

Bu örnekte, longRunningOperation bağlamın iptal edilip edilmediğini kontrol eder. Eğer ana bağlamın zaman aşımı (2 saniye) tamamlanmadan önce (3 saniye) işlem sona ererse, goroutine ctx.Done() üzerinden iptal sinyali alır ve sona erer.