Kann ein Anrufer eine Ausführung von Code abbrechen, der durch eine HTTP-Anforderung aufgerufen wird?

8

Ein Dritter, der HTTP-Anforderungen an die von mir erstellte API stellt, muss in weniger als einer Sekunde antworten. Meine Frage ist, haben sie einen Weg (buchstäblich jede Art und Weise, innerhalb der Grenzen des HTTP und / oder TCP / IP - Protokolle) , um die Ausführung meines Codes abzubrechen , wenn es länger als eine Sekunde dauert?

Kerben
quelle
1
Sie können das Zeitlimit des HttpClient direkt festlegen, aber der auf der Serverseite ausgeführte Code wird dadurch nicht abgebrochen.
Jon Raynor
15
Ja. IP-Geolokalisierung und eine Marschflugkörper. Wenn Sie das nicht im Sinn hatten, müssen Sie mit Ihrem "buchstäblich jeden Weg" viel präziser vorgehen.
Jörg W Mittag
Es könnte zehn Gründe geben, die den Benutzer "glauben lassen" könnten, dass der Prozess länger als 1 Sekunde dauert. Zum Beispiel Latenz. Sie wissen, jemand im Büro, der verdächtige Inhalte herunterlädt ... Bis der Benutzer die Abbruchanforderung sendet, ist der Vorgang möglicherweise erfolgreich abgeschlossen. 1 Sekunde ist zu wenig Zeit (glaube ich) für einen Menschen.
Laiv
@jmoreno Umfasst ich in Ihren "Grenzen" eine Schaltfläche zum Abbrechen, auf die der Benutzer klicken kann? Oder suchen Sie etwas, das im Osi-Stack niedriger ist als in der Anwendungsschicht?
candied_orange
2
Überrascht, dass dies tatsächlich VTC war. Die Antwort ist sicher. Nichts hindert Sie daran, Anforderungen auf irgendeine Weise zu registrieren und einen Endpunkt oder eine API-Methode hinzuzufügen, mit der sie abgebrochen werden - entweder durch native Prozessverwaltung oder indem regelmäßig "stornierbare" Anforderungen überprüft werden, ob sie angewiesen wurden, zu stoppen ...
svidgen

Antworten:

10

HTTP funktioniert so nicht. Der Client sendet eine Anfrage, dann sendet der Server eine Antwort zurück. Es findet keine andere Kommunikation statt. Nun, der Server kann 1xx Informationsantworten vor der Hauptantwort senden. Es gibt jedoch keine Möglichkeit für den Client, Aktualisierungen zu einer gesendeten Anforderung zu senden.

(Bei HTTP / 2, bei dem mehrere Anforderungen über dieselbe Verbindung gemultiplext werden können, ist die Situation sehr unterschiedlich. Ein Client kann einen Stream abbrechen, um anzuzeigen, dass er nicht mehr benötigt wird, nachdem er eine PUSH_PROMISE vom Server empfangen hat. Ich werde HTTP / 2 ignorieren für den Rest dieser Antwort.)

Auch Netzwerke funktionieren so nicht. Siehe insbesondere den zweiten Irrtum des verteilten Rechnens : „Latenz ist Null“. Es ist nicht. Von dieser Zeitüberschreitung von einer Sekunde wurden möglicherweise 400 ms für das Herstellen der Verbindung und das Senden der Anforderung und 600 ms für die Antwort aufgewendet, da eines der Pakete verworfen wurde und Sie alles erneut senden mussten und Ihr Client in Australien ist. Abgesehen von dem Problem, dass der Server möglicherweise nicht genügend Zeit hat, weiß der Server nicht einmal, wie viel Zeit er hat, da die Antwortlatenz nicht im Voraus bekannt sein kann.

Welche Lösung könnte also gut genug sein, da es buchstäblich unmöglich ist, diese Zeitüberschreitungen buchstäblich zu implementieren?

Wenn die Antwort nach dem Timeout keinen Wert mehr hat, kann der Client die Verbindung einfach schließen. Dies führt dazu, dass Ihre Antwort ignoriert wird, verhindert jedoch nicht die Antwort.

Durch Schließen der TCP-Verbindung, über die die HTTP-Anforderung gesendet wird, wird der Server benachrichtigt. Diese Benachrichtigung kommt jedoch nur mit Latenz an, sodass es möglicherweise zu spät ist. Außerdem unternimmt Ihr Webframework möglicherweise nichts, wenn der Client-Socket geschlossen ist. In diesem Fall wird nur dann der Fehler "Verbindung durch Peer zurückgesetzt" angezeigt, wenn Sie versuchen, in den geschlossenen Socket zu schreiben.

Wenn Sie nicht mehr als eine Sekunde für die Verarbeitung der Antwort aufwenden möchten, liegt die Implementierung dieses Zeitlimits ausschließlich in Ihrer Verantwortung und hat nichts mit Netzwerk oder HTTP zu tun.

Sie können den Client bitten, dem Server eine Zeitüberschreitung bereitzustellen, damit der Server abbrechen kann, wenn die Frist nicht eingehalten wird. Dies kann als benutzerdefinierter Header oder als Abfrageparameter in der URL angegeben werden. Diese Frist sollte ein absoluter Zeitpunkt und keine Dauer sein, damit Übertragungsverzögerungen auch die verfügbare Zeit verbrauchen. Eine Genauigkeit von weniger als einer Sekunde ist jedoch schwierig: Der Server und der Client müssen mit der richtigen Zeit synchronisiert werden und eine geeignete Uhr verwenden. Abhängig vom Setup kann jede Zeitquelle bei korrekter Konfiguration um 100 ms ausgeschaltet sein. Dies kostet bereits einen erheblichen Teil Ihres Zeitbudgets.

amon
quelle
Natürlich können Sie eine Zeitüberschreitung als relative Zeit senden. Dies bedeutet nur, dass der Server die Verarbeitung nicht x Sekunden nach dem Senden der Anforderung beenden kann, sondern nur x Sekunden, nachdem der Server sie empfangen hat. Möglicherweise besser, wenn Sie nicht garantieren können, dass Ihre Uhr und die Serveruhr identisch sind. Wenn sie zwei Minuten voneinander entfernt sind, werden möglicherweise alle Anfragen mit einer Zeitüberschreitung von einer Minute (in absoluter Zeit) abgelehnt.
Gnasher729
1

Ich nehme an, sie könnten die Verbindung schließen, aber ich weiß nicht, ob dies tatsächlich zum Abbruch Ihres Codes führen würde - es würde davon abhängen, wie Ihr Code geschrieben ist.

Sie könnten auch eine andere Nachricht senden, die bedeuten könnte, dass Sie zu lange brauchen, also stören Sie sich nicht. In diesem Fall wären Sie wahrscheinlich bereits bereit, eine explizite CANCEL_REQUEST-Nachricht zu verarbeiten.

FrustratedWithFormsDesigner
quelle
Ich denke, das Schreiben an einen geschlossenen Port wird signalisieren, aber Sie können dieses Signal natürlich ignorieren oder verarbeiten (ich weiß dies nur von der Clientseite, wo dieses Problem den Client zum Absturz bringen würde, wenn Sie es nicht behandeln). Abgesehen davon kann der Client den Server nicht zwingen, etwas zu tun. Natürlich kann der Server seine Arbeit freiwillig abbrechen, wenn der Port geschlossen ist, oder die Arbeit abbrechen, wenn sie nicht innerhalb des Zeitlimits ausgeführt wird, oder die Arbeit abbrechen, wenn der Client eine Nachricht sendet, um die Anforderung abzubrechen.
Gnasher729