Maison  >  Article  >  développement back-end  >  Comment utiliser le contexte pour implémenter la fusion des résultats de la demande dans Go

Comment utiliser le contexte pour implémenter la fusion des résultats de la demande dans Go

WBOY
WBOYoriginal
2023-07-22 14:51:251136parcourir

Comment utiliser le contexte pour implémenter la fusion des résultats des requêtes dans Go

Dans les systèmes distribués modernes, il est souvent nécessaire de lancer plusieurs requêtes simultanées en même temps et de fusionner les résultats de ces requêtes. Le package de contexte dans le langage Go offre un moyen élégant de gérer les demandes simultanées dans de tels scénarios et garantit que les demandes non valides peuvent être terminées le plus tôt possible lorsque la demande doit être annulée.

Cet article expliquera comment utiliser le contexte pour fusionner les résultats de la demande et fournira des exemples de code pertinents.

Tout d'abord, comprenons quelques concepts clés et méthodes d'utilisation dans le package contextuel.

  1. Context : le contexte est un objet contextuel qui peut être utilisé pour contrôler la goroutine. Dans les requêtes simultanées, nous pouvons transmettre l'objet contextuel à chaque requête et utiliser l'objet contextuel pour gérer et contrôler ces requêtes.
  2. WithCancel : utilisez la fonction WithCancel(parent) pour créer un nouveau contexte enfant et renvoyer une fonction d'annulation. Lorsque nous voulons annuler le contexte, il suffit d'appeler la fonction Cancel.
  3. WithTimeout : utilisez la fonction WithTimeout(parent, timeout) pour créer un contexte avec un délai d'attente. Après l'heure spécifiée, le contexte sera automatiquement annulé.

Après avoir compris ces concepts de base, nous pouvons commencer à mettre en œuvre la fusion des résultats des requêtes.

Tout d’abord, supposons que nous ayons un service qui doit adresser des requêtes à plusieurs API externes simultanément et fusionner leurs résultats. Nous pouvons utiliser le contexte pour réaliser les fonctions suivantes :

  1. Créer un contexte parent et créer un contexte enfant pour chaque requête.
  2. Dans chaque goroutine, utilisez ces sous-contextes pour envoyer des requêtes et attendre les résultats.
  3. Lorsque toutes les demandes sont terminées, renvoyez les résultats via le canal ou par d'autres moyens.

Ensuite, examinons un exemple de code qui utilise le contexte pour implémenter la fusion des résultats de la requête :

package main

import (
    "context"
    "fmt"
    "net/http"
    "sync"
    "time"
)

func fetchData(ctx context.Context, url string, wg *sync.WaitGroup, ch chan<- string) {
    defer wg.Done()

    req, err := http.NewRequest("GET", url, nil)
    if err != nil {
        ch <- fmt.Sprintf("%s failed: %v", url, err)
        return
    }

    select {
    case <-ctx.Done():
        ch <- fmt.Sprintf("%s cancelled", url)
        return
    default:
    }

    client := http.DefaultClient
    resp, err := client.Do(req)
    if err != nil {
        ch <- fmt.Sprintf("%s failed: %v", url, err)
        return
    }

    select {
    case <-ctx.Done():
        ch <- fmt.Sprintf("%s cancelled", url)
    case <-time.After(1 * time.Second):
        body := make([]byte, 1024)
        _, _ = resp.Body.Read(body)
        ch <- fmt.Sprintf("%s fetched: %s", url, body)
    }

    resp.Body.Close()
}

func main() {
    ctx, cancel := context.WithCancel(context.Background())
    defer cancel()

    urls := []string{"https://www.google.com", "https://www.bing.com", "https://www.baidu.com"}

    var wg sync.WaitGroup
    results := make(chan string, len(urls))

    for _, url := range urls {
        wg.Add(1)
        go fetchData(ctx, url, &wg, results)
    }

    go func() {
        wg.Wait()
        close(results)
    }()

    for res := range results {
        fmt.Println(res)
    }
}

Dans l'exemple de code ci-dessus, nous créons d'abord un contexte parent, puis créons un contexte enfant pour chaque requête.

Dans la fonction fetchData, nous utilisons l'instruction select pour vérifier si le contexte a été annulé. En cas d'annulation, la demande est immédiatement terminée. S'il n'est pas annulé, envoyez la demande et attendez le résultat.

Enfin, nous démarrons plusieurs goroutines dans la fonction principale pour traiter la demande et renvoyer les résultats via le canal. Nous utilisons sync.WaitGroup pour attendre que toutes les demandes soient terminées et pouvons annuler l'intégralité du processus de demande à tout moment via la fonction d'annulation.

Résumé :

En utilisant le package contextuel, nous pouvons gérer les demandes simultanées avec élégance et annuler les demandes invalides en temps opportun en cas de besoin. L'exemple de code ci-dessus montre comment utiliser le contexte pour fusionner les résultats de la demande. En utilisant rationnellement le contexte, nous pouvons améliorer les capacités de traitement simultané du système tout en conservant la clarté et la lisibilité du code.

La clé pour utiliser le contexte est d'utiliser correctement des fonctions telles que WithCancel et WithTimeout pour créer des sous-contextes, et d'utiliser les instructions select dans goroutine pour vérifier s'il faut annuler ou expirer. De cette façon, nous pouvons mettre fin aux demandes invalides à temps lorsque cela est nécessaire et fusionner les résultats des demandes valides.

En comprenant profondément et en utilisant de manière flexible le package de contexte, nous pouvons mieux construire des systèmes distribués simultanés et fiables.

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