Sobes.tech
Junior

Mis on kontekst Go-s?

sobes.tech AI

Vastus AI-lt

Konteksts (context.Context) Go valodā ir objekts, kas nes līdzi termiņu, atcelšanas signālu (cancellation signal) un datus, kas ir specifiski pieprasījumam. To izmanto gorutīnu dzīves cikla pārvaldībai un informācijas pārnešanai starp tām izpildes laikā.

Galvenās īpašības:

  • Drošs vairākām pavedieniem: Var droši pārsūtīt starp gorutīnām.
  • Imutabls: Pēc izveides Context nevar mainīt. Derivātus kontekstus veido uz vecā balstoties.
  • Hierarhisks: Konteksti veido koku ar sakni (context.Background() vai context.TODO()). Vecā konteksta atcelšana noved pie visu bērnu atcelšanas.

context pakotnes galvenās funkcijas:

  • context.Background(): Tukšs konteksts, parasti lieto galvenajā funkcijā, augšējās līnijas pieprasījumos vai testos. Nekad nav atcelts.
  • context.TODO(): Arī tukšs konteksts. Lieto kā aizvietotāju, ja nav zināms, kuru kontekstu izmantot, vai ja funkcionalitāte vēl nav īstenota.
  • context.WithCancel(parent Context): Atgriež jaunu bērnu kontekstu un atcelšanas funkciju. Izsaucot atcelšanas funkciju, šis un visi tā bērni tiek atcelti.
  • context.WithDeadline(parent Context, deadline time.Time): Atgriež bērnu kontekstu, kas automātiski atceljas, kad sasniedz norādīto laiku. Tiek atgriezta arī funkcija manuālai atcelšanai.
  • context.WithTimeout(parent Context, timeout time.Duration): Tāpat kā WithDeadline, bet ar laika ilgumu.
  • context.WithValue(parent Context, key, val interface{}): Atgriež bērnu kontekstu ar piešķirtu vērtību pēc atslēgas.

Piemērs ar context.WithTimeout:

package main

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

func longRunningOperation(ctx context.Context, resultChan chan string) {
	select {
	case <-time.After(3 * time.Second):
		// Operācija veiksmīgi pabeigta
		resultChan <- "Operation completed"
	case <-ctx.Done():
		// Konteksts tika atcelts
		err := ctx.Err() // Saņemam atcelšanas iemeslu
		resultChan <- fmt.Sprintf("Operation cancelled: %v", err)
	}
}

func main() {
	// Izveidojam kontekstu ar 2 sekundžu termiņu
	ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
	defer cancel() // Garantējam atcelšanas funkcijas izsaukšanu

	resultChan := make(chan string, 1)

	go longRunningOperation(ctx, resultChan)

	// Gaidām rezultātu vai atcelšanu
	select {
	case res := <-resultChan:
		fmt.Println(res)
	case <-ctx.Done():
		fmt.Printf("Main context done: %v\n", ctx.Err())
	}

	// Nedaudz pagaidām, lai gorutīna varētu pabeigties, ja tā tika atcelta
	time.Sleep(1 * time.Second)
}

Šajā piemērā longRunningOperation pārbauda konteksta atcelšanu. Ja galvenā konteksta (2 sekundes) termiņš beidzas ātrāk nekā operācija (3 sekundes), gorutīna saņem signālu caur ctx.Done() un beidzas.