web-dev-qa-db-fra.com

Un appelant peut-il annuler une exécution de code invoqué par une requête HTTP?

Un tiers qui va faire des requêtes HTTP à l'API que je construis, requiert que l'API réponde en moins d'une seconde. Ma question est, ont-ils un moyen (littéralement tout moyen, dans les limites des protocoles http et/ou tcp/ip) pour abandonner l'exécution de mon code si cela prend plus d'une seconde?

8
nicks

HTTP ne fonctionne pas comme ça. Le client envoie une demande, puis le serveur renvoie une réponse. Aucune autre communication ne se produit. Eh bien, le serveur peut envoyer des réponses d'information 1xx avant la réponse principale. Mais il n'y a aucun moyen pour le client d'envoyer des mises à jour sur une demande envoyée.

(La situation est très différente pour HTTP/2 qui peut multiplexer plusieurs requêtes sur la même connexion. Un client peut ANNULER un flux pour indiquer qu'il n'est plus nécessaire après avoir reçu une Push_PROMISE du serveur. J'ignore HTTP/2 pour le reste de cette réponse.)

De plus, les réseaux ne fonctionnent pas comme ça. En particulier, voir la seconde erreur de calcul distribué : "la latence est nulle". Ce n'est pas. De ce délai d'une seconde, 400 ms ont peut-être été consacrées à l'établissement de la connexion et à l'envoi de la demande et 600 ms à la réponse, car l'un des paquets a été abandonné et vous avez dû tout renvoyer et votre client est en Australie. Mis à part le problème que le serveur peut ne pas avoir assez de temps, le serveur ne sait même pas combien de temps il a parce que la latence de réponse ne peut pas être connue à l'avance.

Donc, étant donné que la mise en œuvre de ces délais d'expiration est impossible, quel type de solution pourrait être assez bon?

Si la réponse n'aura aucune valeur après le délai d'expiration, le client peut simplement fermer la connexion. Cela entraînera l'ignorance de votre réponse, mais n'empêchera pas la réponse.

La fermeture de la connexion TCP via laquelle la demande HTTP est envoyée avertit le serveur. Mais cette notification arrive uniquement avec une latence, il peut donc être trop tard. De plus, votre infrastructure Web ne fait rien lorsque le socket client est fermé. Dans ce cas, vous n'obtiendrez une erreur "connexion réinitialisée par l'homologue" qu'une fois que vous essayez d'écrire sur le socket fermé.

Si vous ne souhaitez pas consacrer plus d'une seconde au traitement de la réponse, la mise en œuvre de ce délai est entièrement de votre responsabilité et n'a rien à voir avec la mise en réseau ou HTTP.

Vous pouvez demander au client de fournir un délai d'expiration au serveur, afin que le serveur puisse abandonner s'il ne peut pas respecter le délai. Cela peut être spécifié comme en-tête personnalisé ou comme paramètre de requête dans l'URL. Ce délai doit être un point absolu dans le temps et non une durée afin que les retards de transmission consomment également le temps disponible. Mais la précision en moins d'une seconde est difficile: le serveur et le client doivent être synchronisés avec l'heure correcte et doivent utiliser une horloge appropriée. Selon la configuration, chaque source de temps peut être désactivée de 100 ms même lorsqu'elle est correctement configurée. Cela mange déjà une partie importante de votre budget temps.

9
amon

Je suppose qu'ils pourraient fermer la connexion, mais je ne sais pas si cela entraînerait l'abandon de votre code - cela dépendrait de la façon dont votre code est écrit.

Ils pourraient également envoyer un autre message qui pourrait signifier "vous prenez trop de temps, donc ne vous embêtez pas", mais dans ce cas, vous seriez probablement déjà prêt à gérer un message CANCEL_REQUEST explicite.