Sobes.tech
Junior

Go-da kontekst nədir?

sobes.tech Süni İntellekt

AI-dan cavab

Go-da (context.Context) kontekst, son tarix, ləğv siqnalı və sorğu üçün xüsusi məlumatları daşıyan obyektidir. Bu, goroutine-lərin həyat dövrünü idarə etmək və onların arasında məlumat ötürmək üçün istifadə olunur.

Əsas xüsusiyyətlər:

  • Eyni zamanda təhlükəsiz: Güvənli şəkildə goroutine-lər arasında ötürülə bilər.
  • Dəyişməz: Bir dəfə yaradıldıqdan sonra, Context dəyişdirilə bilməz. Törəmə kontekstlər valideynə əsaslanaraq yaradılır.
  • İerarxik: Kontekstlər, (context.Background() və ya context.TODO()) ilə kök olan ağac şəklində formalaşır. Valideyn kontekstin ləğvi, bütün uşaqlarının ləğvinə səbəb olur.

context paketinin əsas funksiyaları:

  • context.Background() : Boş kontekst, adətən main funksiyasında, yüksək səviyyəli sorğularda və ya testlərdə istifadə olunur. Heç vaxt ləğv edilmir.
  • context.TODO() : Həmçinin boş kontekst. Hangi kontekstin istifadə ediləcəyini bilmədikdə və ya kontekst funksionallığı hələ həyata keçirilmədikdə istifadə olunur.
  • context.WithCancel(parent Context) : Yeni uşaq kontekst və ləğv funksiyası qaytarır. Bu funksiyanı çağırmaq, bu kontekst və onun bütün uşaqlarını ləğv edir.
  • context.WithDeadline(parent Context, deadline time.Time) : Verilən vaxta çatdıqda avtomatik ləğv olunan uşaq kontekstini qaytarır. Həmçinin, əl ilə ləğv üçün funksiyanı da qaytarır.
  • context.WithTimeout(parent Context, timeout time.Duration) : Eynilə WithDeadline, lakin müddət ilə.
  • context.WithValue(parent Context, key, val interface{}) : Açar ilə əlaqəli dəyər ilə uşaq kontekstini qaytarır.

Tətbiqlər:

  • Əməliyyatların ləğvi: Məsələn, HTTP sorğusunun vaxt aşımı və ya uzunmüddətli əməliyyatın dayandırılması.
  • Məlumatların ötürülməsi: Məsələn, sorğu ID-si qeydiyyat üçün, autentifikasiya məlumatları.

context.WithTimeout istifadə nümunəsi:

package main

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

func longRunningOperation(ctx context.Context, resultChan chan string) {
	select {
	case <-time.After(3 * time.Second):
		// Əməliyyat uğurla tamamlandı
		resultChan <- "Əməliyyat tamamlandı"
	case <-ctx.Done():
		// Kontekst ləğv edildi
		err := ctx.Err() // Ləğv səbəbini al
		resultChan <- fmt.Sprintf("Əməliyyat ləğv edildi: %v", err)
	}
}

func main() {
	// 2 saniyəlik vaxt aşımı ilə kontekst yaradın
	ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
	defer cancel() // Ləğv funksiyasını çağırmağa zəmanət verin

	resultChan := make(chan string, 1)

	go longRunningOperation(ctx, resultChan)

	// Nəticə və ya ləğv üçün gözləyin
	select {
	case res := <-resultChan:
		fmt.Println(res)
	case <-ctx.Done():
		fmt.Printf("Əsas kontekst tamamlandı: %v\n", ctx.Err())
	}

	// Əgər ləğv olunarsa, goroutine-in bitməsini bir az gözləyin
	time.Sleep(1 * time.Second)
}

Bu nümunədə, longRunningOperation kontekstin ləğv olunub-olunmadığını yoxlayır. Əsas kontekstin vaxt aşımı (2 saniyə) bitməzdən əvvəl (3 saniyə) əməliyyat bitərsə, goroutine ctx.Done() vasitəsilə ləğv siqnalı alır və sona çatır.