Sobes.tech
Junior

Маънои контекст дар Go чист?

sobes.tech AI

Ҷавоб аз AI

Мавқеи (context.Context) дар забони Go объектист, ки борбари мӯҳлат, сигнали бекоркунӣ (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 сония) пеш аз анҷоми амал (3 сония) ба охир расад, горутина сигнали бекорро тавассути ctx.Done() мегирад ва ба охир мерасад.