¿Puede una persona que llama cancelar una ejecución de código invocado por una solicitud HTTP?

8

Un tercero que va a realizar solicitudes HTTP a la API que estoy creando, requiere que la API responda en menos de un segundo. Mi pregunta es, ¿tienen una forma (literalmente cualquier forma, dentro de los límites de los protocolos HTTP y / o protocolos TCP / IP) para cancelar la ejecución de mi código si se tarda más de un segundo?

mellas
fuente
1
Pueden establecer el tiempo de espera del HttpClient directamente, pero eso no anula el código que se ejecuta en el lado del servidor.
Jon Raynor
15
Si. Geolocalización IP y un misil de crucero. Si eso no es lo que tenía en mente, tendrá que ser mucho más preciso con su "literalmente de cualquier manera".
Jörg W Mittag
Podría haber decenas de razones que podrían "hacer creer" al usuario que el proceso lleva más de 1 segundo. Por ejemplo, latencia. Ya sabes, alguien en la oficina descargando contenido sospechoso ... Para cuando el usuario envíe la solicitud de cancelación, el proceso podría haber finalizado con éxito. 1 segundo es poco tiempo (creo) para un humano.
Laiv
@jmoreno ¿Sus "límites" me incluyen agregando un botón de cancelación para que el usuario haga clic? ¿O está buscando algo más bajo en la pila osi que la capa de aplicación?
candied_orange
2
Sorprendido, esto fue VTC'd en realidad. La respuesta es segura. Nada le impide registrar solicitudes de alguna manera y agregar un método de punto final o API que las cancela, ya sea a través de la administración de procesos nativos o haciendo que las solicitudes "
cancelables

Respuestas:

10

HTTP no funciona así. El cliente envía una solicitud, luego el servidor devuelve una respuesta. No se produce otra comunicación. Bueno, el servidor puede enviar respuestas informativas 1xx antes de la respuesta principal. Pero no hay forma de que el cliente envíe actualizaciones sobre una solicitud enviada.

(La situación es muy diferente para HTTP / 2 que puede multiplexar múltiples solicitudes a través de la misma conexión. Un cliente puede CANCELAR una secuencia para indicar que ya no es necesaria después de recibir un PUSH_PROMISE del servidor. Ignoraré HTTP / 2 por el resto de esta respuesta.)

Además, las redes no funcionan así. En particular, vea la segunda falacia de la computación distribuida : "la latencia es cero". No lo es. De ese tiempo de espera de un segundo, es posible que se hayan gastado 400 ms en establecer la conexión y enviar la solicitud y 600 ms en la respuesta, porque uno de los paquetes se descartó y tuvo que reenviar todo y su cliente está en Australia. Además del problema de que el servidor podría no tener suficiente tiempo, el servidor ni siquiera sabe cuánto tiempo tiene porque la latencia de respuesta no se puede conocer de antemano.

Entonces, dado que, literalmente, implementar estos tiempos de espera es imposible, ¿qué tipo de solución podría ser lo suficientemente buena?

Si la respuesta no tendrá valor después del tiempo de espera, el cliente puede simplemente cerrar la conexión. Esto hará que su respuesta sea ignorada, pero no impedirá la respuesta.

Cerrar la conexión TCP a través de la cual se envía la solicitud HTTP notifica al servidor. Pero esta notificación solo llega con latencia, por lo que puede ser demasiado tarde. Además, su marco web puede no estar haciendo nada cuando el socket del cliente está cerrado. En ese caso, solo obtendrá un error "restablecimiento de la conexión por igual" una vez que intente escribir en el socket cerrado.

Si no desea dedicar más de un segundo al procesamiento de la respuesta, la implementación de ese tiempo de espera es totalmente su responsabilidad y no tiene nada que ver con las redes o HTTP.

Puede pedirle al cliente que proporcione un tiempo de espera para el servidor, de modo que el servidor pueda abortar si no puede cumplir con la fecha límite. Esto podría especificarse como un encabezado personalizado o como un parámetro de consulta en la URL. Este plazo debe ser un punto absoluto en el tiempo y no una duración para que los retrasos en la transmisión también consuman el tiempo disponible. Pero la precisión por debajo del segundo es difícil: el servidor y el cliente deben sincronizarse con la hora correcta y deben usar un reloj adecuado. Dependiendo de la configuración, cada fuente de tiempo puede estar apagada en 100 ms, incluso cuando está configurada correctamente. Esto ya consume una parte significativa de su presupuesto de tiempo.

amon
fuente
Por supuesto, puede enviar un tiempo de espera como tiempo relativo; solo significa que el servidor no puede dejar de procesar x segundos después de enviar la solicitud, sino solo x segundos después de que el servidor la recibió. Puede ser mejor si no puede garantizar que su reloj y el reloj del servidor sean iguales. Si están separados por dos minutos, todas las solicitudes con un tiempo de espera de un minuto (en tiempo absoluto) podrían ser rechazadas.
gnasher729
1

Supongo que podrían cerrar la conexión, pero no sé si eso realmente haría que su código se abortara; dependería de cómo esté escrito su código.

También podrían enviar otro mensaje que podría significar "estás tardando demasiado, así que no te molestes", pero en ese caso, probablemente ya estés preparado para manejar un mensaje CANCEL_REQUEST explícito.

FrustratedWithFormsDesigner
fuente
Creo que escribir en un puerto cerrado indicará, pero, por supuesto, puede ignorar o manejar esa señal (solo sé esto desde el lado del cliente, donde este problema haría que el cliente se bloquee si no lo maneja). Aparte de eso, el cliente no puede FORZAR al servidor a hacer nada. Por supuesto, el servidor puede abortar su trabajo voluntariamente si el puerto está cerrado, o abortar el trabajo si no se va a hacer dentro del tiempo de espera, o abortar el trabajo si el cliente envía un mensaje para cancelar la solicitud.
gnasher729