Seit https://github.com/TheThingsNetwork/lorawan-stack/pull/2565 werden die Events im Konsolenblock gestreamt, nachdem man in der Konsole herumgeklickt hat.
Irgendwann lädt die Konsole weiter. Dies scheint durch "zu viele offene Verbindungen" verursacht zu werden, da /api/v3/events
Anfragen nicht geschlossen werden.
Die Konsole sollte reaktionsschnell bleiben.
Build basierend auf dem aktuellen master
Zweig 3df51cd750f57b37c3acffc28b417441babdbf30 (achten Sie nicht auf die 3.8.5, die von der Konsole angezeigt wird)
Ich vermute, dass dies dadurch verursacht wird, dass Header nur direkt vor der ersten Nachricht im Stream geschrieben werden. Wenn keine Nachricht vorhanden ist, gibt es keinen Header und der Browser wartet weiter.
Um dies zu untersuchen, schlage ich vor:
Probieren Sie die Reproduktionsschritte aus
Auf der Firefox-Konsole wird immer geladen, wenn 6 geöffnete Registerkarten vorhanden sind - wenn zB eine der Arbeitsregisterkarten aktualisiert wird - eine der Laderegisterkarten entsperrt, aber das scheint manchmal fehlzuschlagen.
Auf jeden Fall habe ich versucht, die Start- / Endnachrichten zu senden, aber das hat nichts geändert - es hängt immer noch, nachdem es 6 Registerkarten gibt.
Hinweis: Alle Registerkarten befinden sich in der Datenansicht eines Gateways (2 verschiedene)
@kschiffer irgendwelche ideen?
Auf der Firefox-Konsole wird immer geladen, wenn 6 geöffnete Registerkarten vorhanden sind - wenn zB eine der Arbeitsregisterkarten aktualisiert wird - eine der Laderegisterkarten entsperrt, aber das scheint manchmal fehlzuschlagen.
Das wird erwartet und eine Einschränkung, die Ereignisstreams aufhebt, wenn HTTP/2 nicht verwendet wird :
Wenn es nicht über HTTP/2 verwendet wird , leidet SSE unter einer Beschränkung der maximalen Anzahl offener Verbindungen, was beim Öffnen verschiedener Registerkarten besonders schmerzhaft sein kann, da das Limit _pro Browser_ und auf eine sehr niedrige Zahl eingestellt ist (6). Das Problem wurde in Chrome und Firefox als "Wird nicht behoben" gekennzeichnet. Dieses Limit gilt pro Browser + Domain, das heißt, Sie können 6 SSE-Verbindungen über alle Registerkarten zu
www.example1.com
und weitere 6 SSE-Verbindungen zuwww.example2.com.
(von Stackoverflow )
Ich habe Probleme, das ursprüngliche Problem zu reproduzieren, da ich nur Zugriff auf zwei verbundene Gateways in der Staging-Umgebung habe.
Ich vermute, dass dies dadurch verursacht wird, dass Header nur direkt vor der ersten Nachricht im Stream geschrieben werden. Wenn keine Nachricht vorhanden ist, gibt es keinen Header und der Browser wartet weiter.
Dies kann ich bestätigen. Die Anfragen werden angehalten, wenn sie keinen Antwortheader erhalten. Nachdem sechs solcher Verbindungen geöffnet wurden, werden alle nachfolgenden XHRs ebenfalls blockiert.
Vor #2565 war dies kein Problem, da der Event-Stream immer sofort eine "Start-Stream-Nachricht" sendete, was dazu führte, dass die Header gesendet wurden.
Als solches sehe ich es nicht als Frontend-Problem. Das einzige, was am Frontend sinnvoll zu ändern wäre, wäre sicherzustellen, dass blockierte Stream-Verbindungen nach einer bestimmten Zeit beendet werden.
Das Problem tritt also auf, wenn Ereignisströme keine Daten senden. Der XHR, der die Ereignisstromverbindung durchführt, wird erst aufgelöst, nachdem die erste Nachricht empfangen wurde, andernfalls bleibt er im Zustand
pending
hängen. Sobald 6 dieser Verbindungen geöffnet sind, hängen auch alle anderen Verbindungen, da die maximale Anzahl gleichzeitiger TCP-Verbindungen erreicht ist. Es sieht also so aus, als ob der XHR eine Art Bestätigung vom Server erwartet, dass der Stream eingerichtet wurde.Vor #2565 war dies kein Problem, da der Ereignisstream immer eine "Startstream-Nachricht" gesendet hat.
Ich versuche derzeit herauszufinden, ob und wie dies auf der Frontend-Seite behoben werden kann.
Nach meiner Erfahrung hilft das Senden einer "Erstnachricht" bei diesem Problem nicht. Bitte versuchen Sie es mit folgendem Diff:
diff --git a/pkg/events/grpc/grpc.go b/pkg/events/grpc/grpc.go
index 03f229ca0..5a305b5ac 100644
--- a/pkg/events/grpc/grpc.go
+++ b/pkg/events/grpc/grpc.go
@@ -119,6 +119,10 @@ func (srv *EventsServer) Stream(req *ttnpb.StreamEventsRequest, stream ttnpb.Eve
if err := stream.SendHeader(metadata.MD{}); err != nil {
return err
}
+ if err := stream.Send(&ttnpb.Event{}); err != nil {
+ return err
+ }
+ defer stream.Send(&ttnpb.Event{})
for {
select {
Hier ist ein Video:
https://youtu.be/0Ir0lakV-Mc
Ich sehe einen Unterschied.
Auf master
OHNE Diff:
htdvisser % curl -v 'http://localhost:1885/api/v3/events' --compressed -H 'Authorization: Bearer MFRWG.DVTINRZNJDORITWD64NUJRIYVIXWCKJ3Q6VYLQY.E4K63GZ3WWTZGCIFMD7XLN7A7ACA35YCQSMFCBVCTEOMATCYGG6Q' -H 'Accept: text/event-stream' -H 'Content-Type: application/json' --data-raw '{"identifiers":[{"application_ids":{"application_id":"admin-app"}}]}'
* Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 1885 (#0)
> POST /api/v3/events HTTP/1.1
> Host: localhost:1885
> User-Agent: curl/7.64.1
> Accept-Encoding: deflate, gzip
> Authorization: Bearer MFRWG.DVTINRZNJDORITWD64NUJRIYVIXWCKJ3Q6VYLQY.E4K63GZ3WWTZGCIFMD7XLN7A7ACA35YCQSMFCBVCTEOMATCYGG6Q
> Accept: text/event-stream
> Content-Type: application/json
> Content-Length: 68
>
* upload completely sent off: 68 out of 68 bytes
^C
Auf master
MIT dem Diff.
htdvisser % curl -v 'http://localhost:1885/api/v3/events' --compressed -H 'Authorization: Bearer MFRWG.DVTINRZNJDORITWD64NUJRIYVIXWCKJ3Q6VYLQY.E4K63GZ3WWTZGCIFMD7XLN7A7ACA35YCQSMFCBVCTEOMATCYGG6Q' -H 'Accept: text/event-stream' -H 'Content-Type: application/json' --data-raw '{"identifiers":[{"application_ids":{"application_id":"admin-app"}}]}'
* Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 1885 (#0)
> POST /api/v3/events HTTP/1.1
> Host: localhost:1885
> User-Agent: curl/7.64.1
> Accept-Encoding: deflate, gzip
> Authorization: Bearer MFRWG.DVTINRZNJDORITWD64NUJRIYVIXWCKJ3Q6VYLQY.E4K63GZ3WWTZGCIFMD7XLN7A7ACA35YCQSMFCBVCTEOMATCYGG6Q
> Accept: text/event-stream
> Content-Type: application/json
> Content-Length: 68
>
* upload completely sent off: 68 out of 68 bytes
< HTTP/1.1 200 OK
< Content-Type: text/event-stream
< Referrer-Policy: strict-origin-when-cross-origin
< X-Content-Type-Options: nosniff
< X-Frame-Options: SAMEORIGIN
< X-Request-Id: 01EDTX9RGKRGM02YZVWNB3RXJP
< X-Xss-Protection: 1; mode=block
< Date: Wed, 22 Jul 2020 09:22:32 GMT
< Transfer-Encoding: chunked
<
{"result":{"time":"0001-01-01T00:00:00Z"}}
^C
Wir müssen dieses Problem unterscheiden:
Um 2 abzuschwächen, muss der Antwortheader sofort gesendet werden.
Was die Konsole angeht, sollten wir hier eine Sache beachten, wir sollten auch prüfen, ob wir ausstehende Anfragen stornieren. Derzeit können die Anfragen erst abgebrochen werden, wenn die Stream-Verbindung hergestellt wurde.
@kschiffer können Sie Schritte geben, um das Problem in 2 zu reproduzieren?
Ich aktualisiere ständig einen einzelnen Gateway-Daten-Tab und erlebe keine Hänger mit dem neuesten master
(ohne Patch)
Der einfachste Weg besteht darin, ein völlig neues und nicht verbundenes Gateway zu erstellen, da es keine Nachrichten sendet. Navigieren Sie dann sechs Mal zu seiner Übersichtsseite und zurück zur Gateway-Liste.
Dies ist kein spezifisches Problem für Gateway-Ereignisse, sondern übrigens für alle Ereignisströme.
Die Zuweisung wird aufgehoben, da dies kein Problem ist, das von der Konsole ausgeht.
Geschlossen von #2989
Eine temporäre Lösung wurde in https://github.com/TheThingsNetwork/lorawan-stack/pull/2989 eingeführt – eine robustere Lösung muss noch gefunden werden.
Dies ist also entweder etwas in unseren Abhängigkeiten (grpc-gateway löscht die Header nicht richtig) oder in unserem gemeinsamen Code (vielleicht löscht irgendeine grpc- oder http-Middleware die Header nicht).
Das Label bug
da es derzeit keine Auswirkungen auf unsere Nutzer hat.
Bitte eröffnen Sie eine neue Ausgabe, wenn noch etwas zu klären ist.
Hilfreichster Kommentar
Dies ist also entweder etwas in unseren Abhängigkeiten (grpc-gateway löscht die Header nicht richtig) oder in unserem gemeinsamen Code (vielleicht löscht irgendeine grpc- oder http-Middleware die Header nicht).
Das Label
bug
da es derzeit keine Auswirkungen auf unsere Nutzer hat.