Maison  >  Article  >  développement back-end  >  En savoir plus sur l'utilisation de Go Context

En savoir plus sur l'utilisation de Go Context

PHPz
PHPzoriginal
2023-04-05 09:10:37985parcourir

Le contexte dans le langage Go est très simple à utiliser. Presque tous les programmes Go l'utilisent pour transmettre des valeurs dans la plage de requête. Il s'agit d'un objet léger qui permet de transmettre des valeurs au niveau de la requête au-delà des limites de l'API, y compris les signaux d'annulation, les délais, les identifiants de requête, etc.

Dans cet article, nous examinerons en profondeur l'utilisation de Go Context, comprendrons ses avantages et comment l'utiliser pour améliorer les performances et la robustesse de votre application.

Qu'est-ce que Go Context ?

Go Context est une bibliothèque standard du langage Go, utilisée pour gérer les valeurs de portée des requêtes. Il fournit aux applications une méthode légère et transitive pour transmettre les variables demandées entre les goroutines. Il est principalement utilisé pour transmettre les demandes d'annulation, les délais d'attente, les journaux de suivi, le contexte de la demande, les données de la demande, etc.

Contrairement à Context dans d'autres langages de programmation, Go Context possède des propriétés très spéciales :

  • Il est thread-safe.
  • Sa valeur peut être transmise à travers les goroutines.
  • Il peut être annulé ou expiré pour éviter des opérations de longue durée ou imparables.
  • Il peut également être utilisé pour séparer l'annulation de la demande et l'annulation de l'opération réelle.

Scénarios d'utilisation

Go Context est un outil très polyvalent qui peut être utilisé pour des applications dans différents scénarios, dont certains incluent :

  1. Applications Web

Les applications Web sont l'un des scénarios d'utilisation les plus courants. Il facilite la gestion du contexte et des métadonnées spécifiques aux requêtes requises pour traiter les requêtes HTTP. Pendant le traitement des requêtes HTTP, le contexte est utilisé pour transmettre les identifiants de requête, les délais d'attente des requêtes, les signaux d'annulation, etc. entre les gestionnaires. Par exemple, Context est utilisé pour suivre l'état de la session lors de la gestion des connexions Websocket.

  1. Application de service d'arrière-plan

L'application de service d'arrière-plan peut devoir traverser plusieurs API pour fournir des données aux systèmes externes. Le contexte est utilisé dans de telles applications pour terminer plus efficacement les goroutines et constitue le meilleur choix pour de telles applications. Vous pouvez utiliser la fonction standard Context WithCancel pour y parvenir. Si toutes les goroutines utilisent ce contexte, un seul rappel est nécessaire pour arrêter tous les abonnements et nettoyer les ressources.

  1. Opérations de base de données et de fichiers

Go Context est un outil idéal pour gérer les opérations de fichiers et de bases de données volumineuses, car ces opérations peuvent être gourmandes en ressources et en E/S. Dans ce cas, le Contexte est utilisé pour annuler l'opération afin d'éviter les erreurs et les erreurs d'exécution.

  1. Applications distribuées

Dans l'architecture des microservices, le contexte est largement utilisé pour transmettre des informations relatives aux requêtes de l'API à la chaîne d'appel de chaque service. Dans ce cas, l'ID de trace est stocké dans le contexte et transmis lors de la connexion à plusieurs services. Cela facilite le traçage de l’intégralité de la ligne de demande.

Utilisation du contexte

Maintenant que nous comprenons les bases de Go Context, nous allons explorer comment l'utiliser pour gérer les valeurs liées aux requêtes.

  1. Créer un contexte

Dans le langage Go, vous pouvez utiliser context.Background() pour créer un contexte vide de niveau supérieur. Ce contexte est globalement indépendant et ne contient aucune valeur.

ctx := context.Background()

Vous pouvez également utiliser la fonction WithValue() pour créer un contexte avec une valeur. Par exemple, vous pouvez créer un contexte de gestion des requêtes HTTP avec des données de requête et des limites de délai d'expiration. La fonction

ctx := context.WithValue(
        context.Background(),
        "requestId",
        uuid.New())

ctx.Value() utilise ce contexte pour obtenir la valeur du contexte. Dans l'exemple ci-dessous, nous pouvons obtenir des informations de contexte en demandant un identifiant unique.

requestId, ok := ctx.Value("requestId").(value string)
  1. Timeout Signal

En utilisant la fonction context.WithDeadline ou context.WithTimeout, vous pouvez également appliquer un signal d'expiration au contexte pour éviter des processus longs. La fonction

ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()

cancel() est utilisée pour marquer l'état d'annulation du Contexte. Le contexte sera automatiquement annulé lorsqu'un événement de délai d'attente se produit.

select {
case <-timeOutCtx.Done():
         if err := timeOutCtx.Err(); err != nil {
                   fmt.Println("Time out due to: ", err)
         }
case <-time.After(5 * time.Second):
       fmt.Println("Hooray! Request done within 5 sec")
}

Dans cet exemple, nous créons un contexte de timeout de 10 secondes. L'instruction select attend des opérations sur deux canaux. La méthode Done() émet un signal lorsque le contexte est annulé ou expire.

Nous envoyons un court message via le canal du minuteur et attendons 5 secondes. Étant donné que le deuxième argument de notre fonction context.WithTimeout() dure 10 secondes, seule la première route de l'instruction select doit être exécutée.

  1. Context Cancelable

Le contexte est utilisé lors de processus de longue durée, une fonctionnalité d'annulation de signaux qui peut être utilisée pour éviter une charge inattendue sur le système.

Dans l'extrait de code ci-dessous, nous utiliserons context.WithCancel() pour créer un Context, puis utiliserons la fonction Cancel() pour marquer l'état d'annulation du Context. Si la goroutine donnée se termine avant que le contexte ne soit annulé, son signal d'achèvement est envoyé via la méthode Done().

ctx, cancel := context.WithCancel(context.Background())

go func(ctx context.Context) {
      select {
             case <-ctx.Done():
                 fmt.Println("Exiting goroutine")
                 return
             default:
                  fmt.Println("Processing...")
       }
}(ctx)

// Exit after 5 sec
time.AfterFunc(5*time.Second, cancel)

Ici, nous utilisons Done() et la branche par défaut dans goroutine. Si le contexte est annulé ou expire, la méthode Done() renvoie un signal et appelle la fonction Cancel() pour annuler l'exécution de la goroutine.

Dans la fonction principale, nous utilisons la fonction time.AfterFunc() pour appeler la fonction Cancel() de ce Context afin de marquer l'état d'annulation du Context. Cela déclenchera l'annulation de la goroutine après 5 secondes.

  1. Context超时和取消

在处理请求的时间,我们通常需要确保 goroutine 不会无限期地等待,而需要在可接受的时间范围内执行操作。

在下面的代码段中,我们将使用 context.WithTimeout() 函数创建一个带有 5 秒超时限制的 Context。

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

select {
    case <-time.After(5 * time.Second):
       fmt.Println("Request completed")
    case <-ctx.Done():
         fmt.Println("Exit due to: ", ctx.Err())
}

我们也使用了 cancel() 函数,确保 Context 被取消时自动触发。

为了模拟一个长时间的操作,我们使用 time.After(channel)。 当 goroutine 执行时间超过 2 秒时,Context 始终会被取消。 select 语句通过检查两个 channel 的操作结果而“安全地”退出。

总结

在 Go 语言中,Context 是通用工具,用于管理请求范围的数据。它提供了一种非常强大,灵活的方法,以跨 API 边界传递请求范围的值,如取消信号、截止日期、请求 ID 等。

在本文中,我们深入探讨了 Go Context 的一些实际用例,并讨论了一些最佳实践,以优化应用程序的可维护性和性能。

随着应用程序和网络的规模增长,Context 的正确使用和管理变得非常重要。如果用得当,它可以提高应用程序的健壮性和性能,从而确保进行细粒度的请求管理。

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn