Sobes.tech
Middle

Go'da bağlamın kullanım durumları hakkında bana bilgi ver.

sobes.tech yapay zeka

AI'dan gelen yanıt

Go'da bağlam, isteklerin yaşam döngüsünü yönetmek ve goroutine'lerin yürütmesini kontrol etmek için kullanılır. Temel kullanım durumları:

  • İptal: Belirli bir isteğe bağlı olarak ilişkili goroutine zincirini iptal etmeye olanak tanır. Örneğin, bağlantıyı kapatırken veya zaman aşımında.
  • Zaman aşımı: İşlemin tamamlanması için bir son tarih belirler. İşlem bu süre içinde tamamlanmazsa, bağlam iptal edilir. Bu, sonsuz beklemeleri önler.
  • İstekle ilgili verilerin iletimi: Belirli bir isteğe ait verileri (örneğin, kullanıcı kimliği, izleme tanımlayıcısı) çağrı zinciri boyunca, imzalarını değiştirmeden iletmeye olanak tanır.

Kullanım örnekleri:

  1. Sinyalle iptal:

    package main
    
    import (
    	"context"
    	"fmt"
    	"time"
    )
    
    func worker(ctx context.Context, id int) {
    	for {
    		select {
    		case <-ctx.Done():
    			fmt.Printf("İşçi %d kesildi\n", id)
    			return
    		default:
    			fmt.Printf("İşçi %d çalışıyor...\n", id)
    			time.Sleep(500 * time.Millisecond)
    		}
    	}
    }
    
    func main() {
    	ctx, cancel := context.WithCancel(context.Background())
    	defer cancel() // İptali garanti eder
    
    	go worker(ctx, 1)
    	go worker(ctx, 2)
    
    	time.Sleep(2 * time.Second)
    	cancel() // Bağlamı iptal et
    
    	time.Sleep(500 * time.Millisecond) // Goroutine'lerin bitmesini sağlar
    }
    
  2. Zaman aşımı:

    package main
    
    import (
    	"context"
    	"fmt"
    	"time"
    )
    
    func longOperation(ctx context.Context) error {
    	select {
    	case <-time.After(3 * time.Second): // Uzun bir işlemin simülasyonu
    		fmt.Println("İşlem başarıyla tamamlandı")
    		return nil
    	case <-ctx.Done():
    		fmt.Println("İşlem bağlam tarafından iptal edildi:", ctx.Err())
    		return ctx.Err()
    	}
    }
    
    func main() {
    	ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
    	defer cancel()
    
    	err := longOperation(ctx)
    	if err != nil {
    		fmt.Println("Hata:", err)
    	}
    }
    
  3. Verilerin iletimi:

    package main
    
    import (
    	"context"
    	"fmt"
    )
    
    type UserKey string
    
    const userIDKey UserKey = "userID"
    
    func processRequest(ctx context.Context) {
    	userID := ctx.Value(userIDKey).(int)
    	fmt.Printf("İstek işleniyor, kullanıcı ID: %d\n", userID)
    	// Kullanıcı ID'si ile isteğin devamı
    }
    
    func main() {
    	ctx := context.WithValue(context.Background(), userIDKey, 123)
    	processRequest(ctx)
    }
    

Bağlamın kök olarak context.Background() veya context.TODO() kullanılması ve çağrı zinciri boyunca iletilmesi önemlidir. Bağlam, doğrudan yaşam döngüsüyle ilişkili değilse, veri yapılarında saklanmamalıdır.