web-dev-qa-db-fra.com

Comprendre le délai d'expiration du contexte de Golang

J'ai du mal à comprendre comment vérifier si le contexte a dépassé le délai fixé par le délai d'attente, ou si je devrais vérifier du tout?

Ceci est un extrait de mongo-go-driver:

client, err := NewClient("mongodb://foo:bar@localhost:27017")
if err != nil { return err }
ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second)
defer cancel()
err = client.Connect(ctx)
if err != nil { return err }

En lisant ce code, comment savoir si le contexte a dépassé la date limite? D'après ce que je comprends naïvement (ou ne comprends pas), la ligne err = client.Connect(ctx) me donnera une erreur, y compris le délai dépassé (si dépassé), donc je pense que je n'ai même pas besoin de vérifier explicitement?

Mais ensuite, en parcourant Internet pour mieux comprendre le fonctionnement des contextes, je rencontre des utilisations de cas sélectionnés qui vérifient explicitement les contextes comme ci-dessous (extrait de code de http://p.agnihotry.com/post/understanding_the_context_package_in_golang/ ):

//Use a select statement to exit out if context expires
  select {
  case <-ctx.Done():
    fmt.Println("sleepRandomContext: Time to return")
  case sleeptime := <-sleeptimeChan:
    //This case is selected when processing finishes before the context is cancelled
    fmt.Println("Slept for ", sleeptime, "ms")
  }

Dois-je le vérifier explicitement? Sinon, quand dois-je utiliser des contrôles explicites? Merci pour votre temps et votre aide!

9
Leesa

Le code select dans la deuxième partie de votre question est à quoi pourrait ressembler le code de la méthode Connect. Là, il vérifie si la ctx.Done() est prête à envoyer. Si tel est le cas, le contexte a été annulé soit parce que le délai d'attente s'est produit, soit parce que cancel() a été appelé.

les erreurs sont des valeurs. Traitez-les comme tels. S'il est important pour vous de comprendre la cause de l'erreur (panne du réseau? Données inattendues? Délai d'attente?), Vous devez alors faire la vérification et agir en conséquence. Si la récupération de l'erreur quelle qu'en soit la cause est la même, la vérification de l'erreur n'est pas comme importante.

4
sberry

Un context est mieux utilisé pour gérer le cycle de vie de quelque chose. Par conséquent, si vous faites quelque chose (par exemple, le traitement d'un fichier), vous devez vérifier le contexte pour vous assurer que le processus n'a pas été traité.

Il existe deux façons de vérifier si un context a été annulé ou expiré:

  1. Context.Done() - Cela renvoie un canal qui sera fermé lorsque le contexte sera annulé.
  2. Context.Err() - Cela retournera une erreur si le contexte est annulé.

Choisissez celui qui correspond le mieux à vos besoins. Si vous faites des choses avec des canaux, l'utilisation de la fonction context.Done() dans un select fonctionne bien. Si vous utilisez une boucle for pendant la lecture d'un io.Reader, La vérification de context.Err() est plus facile.

Cela étant dit, si vous démarrez quelque chose qui prend également un contexte, vous devez toujours utiliser le contexte que vous avez déjà si vous souhaitez que cette nouvelle "chose" soit annulée si vous l’avez été.

2
poy