Sobes.tech
Middle

Go tilida kontekstlar qanday tuzilgan?

sobes.tech AI

AIdan javob

Go tilida (context.Context) kontekst, API chegaralarida ma'lumotlarni uzatish uchun ishlatiladi. U daraxt shaklida: har bir kontekst boshqa birining bolasi bo'lib, faqat ildiz (context.Background() yoki context.TODO()) bundan mustasno.

context.Context interfeysining asosiy metodlari:

  • Deadline() (deadline time.Time, ok bool): Kontekstning deadline'ini qaytaradi.
  • Done() <-chan struct{}: Kontekst bekor qilinganda yopiladigan kanalni qaytaradi.
  • Err() error: Kontekstning bekor qilinishiga olib kelgan xatoni qaytaradi.
  • Value(key any) any: Kontekstdagi kalit bilan bog'langan qiymatni qaytaradi.

Ular context paketining funksiyalari yordamida yaratiladi:

  • context.Background(): Asosiy bo'sh kontekst, asos sifatida ishlatiladi.
  • context.TODO(): Qachonki qaysi kontekstni ishlatishni bilmasangiz, belgilash uchun ishlatiladi.
  • context.WithCancel(parent Context): Farzand kontekst va bekor qilish funksiyasini yaratadi.
  • context.WithDeadline(parent Context, d time.Time): Deadline bilan farzand kontekst yaratadi.
  • context.WithTimeout(parent Context, timeout time.Duration): Timeout bilan farzand kontekst yaratadi.
  • context.WithValue(parent Context, key, val any): Qiymat bilan farzand kontekst yaratadi.

Context ning asosiy amalga oshirishlari:

  • emptyCtx: Asosiy, bekor qilinmaydigan va qiymatga ega emas. Background va TODO ishlatiladi.
  • cancelCtx: Bekor qilishni qo'llab-quvvatlaydi. Asosiy kontekst va bekor qilish kanali bilan tashkil topgan.
  • timerCtx: Deadline/timeout qo'llab-quvvatlaydi. cancelCtx va timerni o'z ichiga oladi.
  • valueCtx: Qiymatlarni uzatishni qo'llab-quvvatlaydi. Asosiy kontekst va kalit-qiymat juftliklarini o'z ichiga oladi.

Ota kontekst bekor qilinganda, uning barcha bolalari avtomatik ravishda bekor qilinadi. Bu bekor qilish signallarini yoki deadline'larni zanjir bo'ylab tarqatishga imkon beradi.

context.WithCancel dan foydalanish misoli:

package main

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

func main() {
	// Asosiy kontekst va bekor qilish funksiyasini yaratamiz
	ctx, cancel := context.WithCancel(context.Background())
	defer cancel() // Maindan chiqishda bekor qilishni ta'minlaydi

	go func() {
		select {
		case <-ctx.Done(): // Kontekst bekor qilinishini kutamiz
			fmt.Println("Vazifa bekor qilindi:", ctx.Err())
			return
		case <-time.After(5 * time.Second): // Yoki 5 sekund o'tgach
			fmt.Println("Vazifa tugadi")
		}
	}()

	// Boshqa joydan kontekstni bekor qilish
	time.Sleep(1 * time.Second)
	fmt.Println("Kontekst bekor qilinmoqda...")
	cancel()

	// Bekor qilishni ishlash uchun vaqt beramiz
	time.Sleep(100 * time.Millisecond)
}

context.WithValue dan foydalanish misoli:

package main

import (
	"context"
	"fmt"
)

type userIDKey string

func processRequest(ctx context.Context) {
	if userID, ok := ctx.Value(userIDKey("UserID")).(string); ok {
		fmt.Println("Foydalanuvchi ID uchun so'rovni ishlash:", userID)
	} else {
		fmt.Println("Kontekstda User ID topilmadi")
	}
}

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

Kontekstlar xavfsiz va o'zgarmas bo'lib, ko'p oqimli kod uchun muhimdir. Ular funksiyalarning xom parametrlarini uzatish uchun emas, balki jarayon bajarilishiga ta'sir qiluvchi meta ma'lumotlar uchun mo'ljallangan.