Sobes.tech
Middle

Kuidas on üles ehitatud kontekstid Go keeles?

sobes.tech AI

Vastus AI-lt

Kontekst (context.Context) Go keeles kasutatakse teabe edastamiseks tähtaegade, tühistamise ja muude andmete vahel API piiride vahel. See on puu struktuur: iga kontekst on teise lapse, välja arvatud juur (context.Background() või context.TODO()).

Peamised context.Context liidese meetodid:

  • Deadline() (deadline time.Time, ok bool): Tagastab konteksti tähtaega.
  • Done() <-chan struct{}: Tagastab kanali, mis suletakse, kui kontekst tühistatakse.
  • Err() error: Tagastab vea, mis viis konteksti tühistamiseni.
  • Value(key any) any: Tagastab väärtuse, mis on seotud võtmega kontekstis.

Loodud context paketi funktsioonidega:

  • context.Background(): Juure tühi kontekst, mida kasutatakse põhiprotsessi alusena.
  • context.TODO(): Kasutatakse asendajana, kui pole teada, millist konteksti kasutada.
  • context.WithCancel(parent Context): Loob lapsekonteksti ja tühistamise funktsiooni.
  • context.WithDeadline(parent Context, d time.Time): Loob lapsekonteksti tähtaega.
  • context.WithTimeout(parent Context, timeout time.Duration): Loob lapsekonteksti ajapiiranguga.
  • context.WithValue(parent Context, key, val any): Loob lapsekonteksti väärtusega.

Peamised Context teostused:

  • emptyCtx: Põhja, mitte-tühistatav ja ilma väärtusteta. Kasutatakse Background ja TODO.
  • cancelCtx: Toetab tühistamist. Koosneb põhikontekstist ja tühistamise kanalist.
  • timerCtx: Toetab tähtaega/ajapiirangut. Sisaldab cancelCtx ja taimerit.
  • valueCtx: Toetab väärtuste edastamist. Sisaldab põhikontexti ja võtme-väärtuse paari.

Kui vanemkontekst tühistatakse, tühistatakse automaatselt kõik selle lapsed. See võimaldab levitada tühistamis- või tähtaegsignaale kogu kutsesüsteemis.

Näide kasutades context.WithCancel:

package main

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

func main() {
	// Loome juurekonteksti ja tühistamise funktsiooni
	ctx, cancel := context.WithCancel(context.Background())
	defer cancel() // Tagab tühistamise programmi lõpus

	go func() {
		select {
		case <-ctx.Done(): // Ootab konteksti tühistamist
			fmt.Println("Ülesanne tühistatud:", ctx.Err())
			return
		case <-time.After(5 * time.Second): // Või lõpetab 5 sekundiga
			fmt.Println("Ülesanne lõpetatud")
		}
	}()

	// Tühistab konteksti teisest kohast
	time.Sleep(1 * time.Second)
	fmt.Println("Tühistame konteksti...")
	cancel()

	// Annab aega gorutinale tühistamise töötlemiseks
	time.Sleep(100 * time.Millisecond)
}

Näide kasutades 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("Käsitlen taotlust kasutaja ID-ga:", userID)
	} else {
		fmt.Println("Kasutaja ID puudub kontekstis")
	}
}

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