Sobes.tech
Middle

როგორ არის მოწყობილი კონტექსტები Go ენისთვის?

sobes.tech AI

პასუხი AI-სგან

context (context.Context) Go-да API шекаралары арасында маалыматтарды өткөрүү үчүн колдонулат. Ал убакыт чектөөлөрү, жокко чыгаруу жана башка маалыматтарды камтыйт. Ал дарак түрүндө: ар бир контекст башка биринин баласы болуп саналат, корутунду (context.Background() же context.TODO()) исключением.

context.Context интерфейсинин негизги ыкмалары:

  • Deadline() (deadline time.Time, ok bool): Контексттин мөөнөтүн кайтарат.
  • Done() <-chan struct{}: Контекст жокко чыгарылганда жабылуучу каналды кайтарат.
  • Err() error: Жокко чыгарууга алып келген катаны кайтарат.
  • Value(key any) any: Контекстте ачкычка байланыштуу маанини кайтарат.

context пакети аркылуу түзүлөт:

  • context.Background(): Тамырсыз бош контекст, негизги процесстин негизги базасы катары колдонулат.
  • context.TODO(): Убактылуу ордуна колдонулат, кайсы контекстти колдонуу керектиги белгисиз учурда.
  • context.WithCancel(parent Context): Балдар контекстин жана жокко чыгаруу функциясын түзөт.
  • context.WithDeadline(parent Context, d time.Time): Мөөнөтү бар балдар контекстин түзөт.
  • context.WithTimeout(parent Context, timeout time.Duration): Время чектөө менен балдар контекстин түзөт.
  • context.WithValue(parent Context, key, val any): Маалымат менен балдар контекстин түзөт.

Негизги Context реализациялары:

  • emptyCtx: Негизги, жокко чыгарылбайт жана маанилери жок. Background жана TODO колдонулат.
  • cancelCtx: Жокко чыгарууну колдойт. Негизги контекст жана жокко чыгаруу каналынын курамынан турат.
  • timerCtx: Мөөнөт/таймер колдойт. cancelCtx жана таймерди камтыйт.
  • valueCtx: Маалыматтарды өткөрүүгө колдойт. Негизги контекст жана ачкыч-маани тандоосун камтыйт.

Ата-энеси контекст жокко чыгарылса, автоматтык түрдө бардык балдары да жокко чыгат. Бул жокко чыгаруу сигналдарын же мүнөттөрдү чынжыр аркылуу жайылтууга мүмкүндүк берет.

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

package main

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

func main() {
	// Негизги контекст жана жокко чыгаруу функциясын түзүү
	ctx, cancel := context.WithCancel(context.Background())
	defer cancel() // Гарантирует отмену при выходе из main

	go func() {
		select {
		case <-ctx.Done(): // Чекор од жокко чыгаруу контекста
			fmt.Println("Задача отменена:", ctx.Err())
			return
		case <-time.After(5 * time.Second): // Или завершается через 5 секунд
			fmt.Println("Задача выполнена")
		}
	}()

	// Отмена контекста из другого места
	time.Sleep(1 * time.Second)
	fmt.Println("Отмена контекста...")
	cancel()

	// Даем время горутине обработать отмену
	time.Sleep(100 * time.Millisecond)
}

Пример использования context.WithValue:

package main

import (
	"context"
	"fmt"
)

type userIDKey string

func processRequest(ctx context.Context) {
	if userID, ok := ctx.Value(userIDKey("UserID")).(string); ok {
		fmt.Println("Processing request for User ID:", userID)
	} else {
		fmt.Println("User ID not found in context")
	}
}

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

Контексты потокобезопасны и неизменяемы, что важно для конкуррентного кода. Они не предназначены для передачи необработанных параметров функции, а скорее для метаинформации, влияющей на выполнение процесса.