Sobes.tech
Junior

Ի՞նչ է կոնտեքստը Go-ում։

sobes.tech AI

Պատասխան AI-ից

Կոնտեքստը (context.Context) Go լեզվում՝ օբյեկտ է, որը կրում է ժամկետ, չեղարկման նշան (cancellation signal) և տվյալներ, որոնք հատուկ են հարցումին։ Այն օգտագործվում է գորուտինների կյանքի ցիկլը կառավարելու և տեղեկատվություն փոխանցելու համար նրանց միջև՝ մեկ հարցում/գործողության ընթացքում։

Հիմնական հատկանիշներ՝

  • Անվտանգ է թելերի համար՝ կարող է անվտանգ փոխանցվել գորուտինների միջև։
  • Անփոփոխ է՝ ստեղծվելուց հետո Context-ը չի կարող փոխվել։ Դերիվատիվ կոնտեքստերը ստեղծվում են ծնողի հիման վրա։
  • Իերարխիկ՝ կոնտեքստերը ձևավորում են ծառ, որի արմատը context.Background() կամ context.TODO()։ Ծնող կոնտեքստի չեղարկումը հանգեցնում է բոլոր դուստրերի չեղարկմանը։

context փաթեթի հիմնական գործառույթները՝

  • context.Background()՝ դատարկ կոնտեքստ, սովորաբար օգտագործվում է main ֆունկցիայում, վերևի հարցումներում կամ թեստերում։ Չեղարկվում է երբեք։
  • 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()-ով և ավարտվում։