Maison >développement back-end >Golang >Comment pouvons-nous garantir la priorité d'annulation du contexte dans l'instruction « select » de Go ?

Comment pouvons-nous garantir la priorité d'annulation du contexte dans l'instruction « select » de Go ?

DDD
DDDoriginal
2024-12-20 02:09:13365parcourir

How Can We Guarantee Context Cancellation Priority in Go's `select` Statement?

Donner la priorité à l'instruction Go select

Problème :

Dans une instruction Go select, la commande L’évaluation des blocs de cas n’est pas déterministe. Cela peut conduire à des situations dans lesquelles un bloc de cas spécifique n'est pas saisi rapidement, même lorsque son canal correspondant est prêt à recevoir.

Scénario :

Envisagez un sendRegularHeartbeats() fonction qui envoie périodiquement des messages de battement de cœur et se termine lorsque son contexte est annulé. Si le contexte est annulé avant l'envoi du premier message de battement de cœur, nous ne nous attendons à ce qu'aucun message de battement de cœur ne soit transmis.

Problème d'évaluation non déterministe :

Dans certains cas , un message de battement de cœur est envoyé malgré l'annulation du contexte avant le démarrage de la fonction. En effet, l'ordre d'évaluation est imprévisible et le cas par défaut ou le cas de battement de cœur peut être saisi avant le cas contextuel.

Suggestion incorrecte :

Une solution proposée est pour ajouter une vérification "isContextclosed" dans le cas du battement de coeur. Cependant, ce n'est pas une solution fiable car les canaux de contexte et de battement de cœur peuvent être prêts à être lus simultanément.

Solution proposée : Primordial Select

Pour prioriser le cas de contexte , nous pouvons introduire une instruction select primordiale qui teste si le canal contextuel est prêt. Ce n'est que si le canal contextuel n'est pas prêt que la deuxième instruction select sera exécutée.

func sendRegularHeartbeats(ctx context.Context) {
    for {
        // Primordial select: Check for context channel being ready only.
        select {
        case <-ctx.Done():
            return
        default:
        }

        // Secondary select: Handle heartbeat logic.
        select {
        case <-ctx.Done():
            return
        case <-time.After(1 * time.Second):
            sendHeartbeat()
        }
    }
}

Imperfection :

Bien que cette approche donne effectivement la priorité au cas contextuel, elle peut autoriser toujours des événements « assez proches ». Par exemple, si un événement de battement de cœur arrive peu de temps après que le canal contextuel soit prêt, le battement de cœur peut être envoyé avant la saisie du cas contextuel. Il n'existe pas de solution parfaite à ce problème avec l'implémentation actuelle du langage Go.

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