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
Contextdeğiştirilemez. Türev bağlamlar, ebeveynlerine dayanarak oluşturulur. - Hiyerarşik: Bağlamlar, kök (
context.Background()veyacontext.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):WithDeadlineile 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.