Sobes.tech
Junior

Go-догу контекст деген эмне?

sobes.tech AI

AIден жооп

Go тилиндеги (context.Context) объект — бул, ал белгилүү бир убакытка чейин иштөө мөөнөтүн, жокко чыгаруу сигналын (cancellation signal) жана суроо-талабга тиешелүү маалыматтарды алып жүрөт. Ал горутиндердин жашоо циклин башкаруу жана алардын ортосунда маалымат алмашуу үчүн колдонулат.

Негизги өзгөчөлүктөрү:

  • Тиркемелерге коопсуз: Горутиндер ортосунда коопсуз өткөрүлүшү мүмкүн.
  • Иммутабель: Бир жолу түзүлгөндөн кийин, Context өзгөртүлбөйт. Мураскор контексттер ата-эне негизинде түзүлөт.
  • Иерархиялык: Контексттер дарак түзөт, тамыры (context.Background() же context.TODO()) менен. Ата-эне контекстин жокко чыгаруу бардык балдарын жокко чыгарат.

context пакети негизги функциялары:

  • context.Background(): Бош контекст, көбүнчө негизги функцияда, жогорку деңгээлдеги суроолордо же тесттерде колдонулат. Эч качан жокко чыгарылбайт.
  • context.TODO(): Ошондой эле бош контекст. Кайда колдонуу керектиги белгисиз учурда, же контексттин функционалдуулугу ишке ашырылбаган учурда колдонулат.
  • context.WithCancel(parent Context): Жаңы балдар контекстин жана жокко чыгаруу функциясын кайтарат. Жокко чыгаруу функциясын чакырганда, бул контекст жана анын бардык балдары жокко чыгат.
  • context.WithDeadline(parent Context, deadline time.Time): Автоматтык түрдө белгиленген убакытта жокко чыгат. Ошондой эле, кол менен жокко чыгаруу үчүн функцияны кайтарат.
  • context.WithTimeout(parent Context, timeout time.Duration): WithDeadline сыяктуу, бирок убакытты белгилейт.
  • context.WithValue(parent Context, key, val interface{}): Ключ менен маанини белгилеген балдар контекстин кайтарат.

Колдонуу:

  • Иштерди жокко чыгаруу: Мисалы, HTTP суроо убакыт чегин белгилөө же узак ишти токтотуу.
  • Маалыматты өткөрүү: Мисалы, суроо IDси логдоо үчүн, аутентификация маалыматы.

context.WithTimeout колдонуу мисалы:

package main

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

func longRunningOperation(ctx context.Context, resultChan chan string) {
	select {
	case <-time.After(3 * time.Second):
		// Иш ийгиликтүү аяктады
		resultChan <- "Operation completed"
	case <-ctx.Done():
		// Контекст жокко чыгарылды
		err := ctx.Err() // Жокко чыгаруу себебин алуу
		resultChan <- fmt.Sprintf("Operation cancelled: %v", err)
	}
}

func main() {
	// 2 секунд убакыт чегинде контекст түзүү
	ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
	defer cancel() // Жокко чыгаруу функциясын чакырууну кепилдөө

	resultChan := make(chan string, 1)

	go longRunningOperation(ctx, resultChan)

	// Натыйжа же жокко чыгаруу күтүү
	select {
	case res := <-resultChan:
		fmt.Println(res)
	case <-ctx.Done():
		fmt.Printf("Main context done: %v\n", ctx.Err())
	}

	// Бир аз күтүп, горутинанын аяктоо мүмкүнчүлүгүн берүү
	time.Sleep(1 * time.Second)
}

Бул мисалда longRunningOperation контексттин жокко чыгарылышын текшерет. Эгер негизги контексттин убакыт чеги (2 секунд) эрте аяктап калса, ал ctx.Done() аркылуу жокко чыгаруу сигналын алат жана аяктайт.