Maison >développement back-end >Golang >Pourquoi `defer Cancel()` est-il crucial pour éviter les fuites de contexte dans Go ?

Pourquoi `defer Cancel()` est-il crucial pour éviter les fuites de contexte dans Go ?

Mary-Kate Olsen
Mary-Kate Olsenoriginal
2024-11-17 19:13:02928parcourir

Why is `defer cancel()` crucial to prevent context leaks in Go?

Fuite de contexte dans Go : implications du saut d'annulation différée()

Dans Go, le package de contexte fournit un moyen de transmettre l'annulation aux opérations simultanées. routines. La fonction context.WithTimeout crée un nouveau contexte avec un délai d'attente qui sera annulé après la durée spécifiée. Si la fonction d'annulation résultante n'est pas appelée, une fuite de contexte se produira.

Dans l'extrait de code fourni :

func Call(ctx context.Context, payload Payload) (Response, error) {
    req, err := http.NewRequest(...)
    ctx, cancel = context.WithTimeout(ctx, time.Duration(3) * time.Second)
    //defer cancel() missing here
    return http.DefaultClient.Do(req)
}

Sans l'instruction defer Cancel(), la fonction d'annulation n'est pas invoquée et la goroutine créée par WithTimeout continue d'exister indéfiniment. Il s'agit d'une fuite de mémoire car la goroutine restera en mémoire jusqu'à la sortie du programme, même si la requête est terminée.

L'outil go vet avertit de cette fuite car elle peut entraîner une consommation excessive de mémoire si la fuite se produit fréquemment. Les fuites de mémoire chroniques peuvent éventuellement entraîner des problèmes de performances du système, voire des crashs.

Pour éviter les fuites de contexte, il est crucial d'appeler la fonction d'annulation lorsque le contexte n'est plus nécessaire. La meilleure pratique consiste à utiliser une instruction defer Cancel() immédiatement après avoir appelé WithCancel ou WithTimeout, comme indiqué dans le code modifié suivant :

func Call(ctx context.Context, payload Payload) (Response, error) {
    req, err := http.NewRequest(...)
    ctx, cancel = context.WithTimeout(ctx, time.Duration(3) * time.Second)
    defer cancel() // Added defer cancel() to release resources
    return http.DefaultClient.Do(req)
}

En adhérant à cette pratique, vous vous assurez que la goroutine et les ressources associées sont publiés rapidement après utilisation, minimisant ainsi le risque de fuite de mémoire et optimisant les performances du système.

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