Comprensione dei contesti in Go

Comprensione dei contesti in Go

Il contesto è una delle funzionalità critiche di Go che abilita la concorrenza. In Go, “contesto” si riferisce a un pacchetto che fornisce funzionalità per valori con ambito di richiesta e segnali di annullamento oltre i limiti dell’API.

Il pacchetto di contesto funziona simultaneamente con il modello di concorrenza di Go, basato sul concetto di goroutine. Le goroutine sono thread di esecuzione leggeri che puoi creare e gestire in modo efficiente, semplificando la creazione di programmi simultanei in Go.

Il pacchetto di contesto

Il pacchetto di contesto fornisce funzionalità per l’annullamento di funzioni a esecuzione prolungata o di intere catene di chiamate. Il pacchetto aiuta anche a memorizzare i valori con ambito di richiesta per l’accesso ovunque all’interno della catena di chiamate. Questa funzionalità è utile quando si lavora con API o microservizi, in cui le richieste possono estendersi su più chiamate di funzione e si desidera annullarle o allegare valori specifici.

Ecco come puoi importare il pacchetto di contesto nei tuoi programmi Go.

import "context"

Le funzioni di contesto accettano il tipo struct Context del pacchetto di contesto. Convenzionalmente, dovresti usare ctx come nome della variabile di istanza.

func operations(ctx context.Context) {
}

Le funzioni possono restituire il tipo struct Context per altre funzioni e operazioni.

func operations(ctx context.Context) context.Context {
}

Puoi creare un nuovo contesto con la funzione TODO del pacchetto di contesto. La funzione TODO crea un nuovo contesto con il valore di context.Done() , un canale che si chiuderà all’annullamento del contesto. Dovresti usarlo come segnaposto quando hai bisogno di un contesto ma nessun contesto genitore è adatto.

import "context"

func main() {
    ctx: = context.TODO()
}

In alternativa, la funzione Sfondo crea un nuovo contesto senza valore e un canale Fatto vuoto.

ctx: = context.Background()

Dovresti usare la funzione Background come radice di un albero di contesto.

Contesto Con Valori

Il pacchetto di contesto fornisce funzionalità per la propagazione di valori e segnali di annullamento. È possibile utilizzare i valori per le informazioni dai dati con ambito di richiesta ai segnali di annullamento e alle scadenze.

Il pacchetto context consente anche la creazione di contesti figli ereditati dai contesti genitori, consentendo una gestione efficiente dei valori e dei segnali di cancellazione in tutto un programma poiché è possibile passare il contesto attraverso più funzioni.

Ecco un esempio di passaggio del contesto attraverso le funzioni con il pacchetto context.

import (
    "context"
)

func valuableContext(ctx context.Context) context.Context {
    return context.WithValue(ctx, "pass-key", "hfouneqcelkwfu")
}


func receiveContextData(ctx context.Context) any {
    passKey: = ctx.Value("pass-key")
    return passKey
}

La funzione validContext accetta un’istanza di contesto e restituisce un’istanza di contesto per la seguente funzione. L’istanza di contesto è un valore creato con il metodo WithValue . Il metodo WithValue accetta l’istanza del contesto dalla funzione e una coppia chiave-valore.

Per recuperare i dati dal contesto, dovrai creare un nuovo contesto con la funzione TODO o Background e passare il contesto alla funzione (in questo caso, validContext) e ricevere il contesto con la funzione receiveContextData .

func main() {
    ctx: = context.Background()
    ctx = valuableContext(ctx)
    fmt.Println(receiveContextData(ctx))

}

La variabile ctx è l’istanza di contesto della funzione Background. La funzione validContext accetta la variabile ctx e restituisce il contesto con un valore che la funzione receiveContextData accetta e restituisce il valore dalla coppia chiave-valore.

contesto in base al risultato del codice valore

Contesto Timeout e scadenze

Il pacchetto di contesto fornisce funzionalità per l’impostazione di timeout e scadenze nelle operazioni. L’impostazione di timeout e scadenze è utile per le operazioni che devono recuperare il ritardo.

I timeout sono la durata del tempo impiegato da un’operazione. È possibile impostare un timeout affinché un’operazione duri 4 secondi; successivamente, il contesto annulla la richiesta.

D’altra parte, una scadenza definisce il punto assoluto in cui un’operazione deve essere annullata.

È possibile utilizzare il metodo WithTimeout per impostare un timeout del contesto. Ecco come impostare un timeout di 2 secondi.

func main() {
    ctx, cancel: = context.WithTimeout(context.Background(), 2 * time.Second)
    defer cancel()

    // some operation
}

La funzione main crea un contesto con un timeout di due secondi. La funzione WithTimeout restituisce una funzione di annullamento che è possibile rinviare per l’annullamento all’uscita della funzione principale.

È possibile dichiarare le scadenze con il metodo WithDeadline . Il metodo WithDeadline accetta un’istanza di contesto e un’ora di scadenza.

func doSomething(ctx context.Context) {
    deadlineTime: = time.Now().Add(1500 * time.Millisecond)
    ctx, ctxCancel: = context.WithDeadline(ctx, deadlineTime)
    defer ctxCancel()

    // some operation


    ctxCancel()
}

La funzione doSomething prende in un contesto e la variabile scadenzaTime è il tempo prima della scadenza del contesto . La variabile ctx è il contesto con una scadenza.

La variabile ctxCancel annulla il contesto quando il contesto supera la scadenza.

Best practice per l’utilizzo dei contesti in Go

Evita di usare i contesti come variabili globali. L’uso dei contesti come variabili globali può portare a comportamenti del codice imprevisti ed errori difficili da tracciare e utilizzare il contesto con parsimonia per ridurre la complessità del codice.

Infine, usa i contesti come segnali, non come garanzie. L’annullamento di un contesto non garantisce che tutte le goroutine smettano di funzionare; è solo un segnale e le goroutine sono agnostiche dei contesti.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *