Desde https://github.com/TheThingsNetwork/lorawan-stack/pull/2565, los eventos se transmiten en el bloque de la consola después de hacer clic en la consola.
En algún momento, la consola sigue cargándose. Esto parece deberse a "demasiadas conexiones abiertas" porque las solicitudes /api/v3/events
no están cerradas.
La consola debe seguir respondiendo.
Construya sobre la base de la actual master
branch 3df51cd750f57b37c3acffc28b417441babdbf30 (no preste atención al 3.8.5 que se muestra en la consola)
Sospecho que esto se debe al hecho de que los encabezados solo se escriben justo antes del primer mensaje en la transmisión. Si no hay mensaje, no hay encabezado y el navegador sigue esperando.
Entonces, para investigar, sugiero:
Prueba los pasos de reproducción
En la consola de Firefox se está cargando para siempre si hay 6 pestañas abiertas, si, por ejemplo, una de las pestañas de trabajo se actualiza, una de las pestañas de carga se desbloquea, pero a veces parece fallar.
En cualquier caso, intenté enviar los mensajes de inicio / finalización, pero eso no cambió nada; todavía se cuelga después de que haya 6 pestañas.
Nota: todas las pestañas están en la vista de datos de una puerta de enlace (2 diferentes)
@kschiffer ¿ alguna idea?
En la consola de Firefox se está cargando para siempre si hay 6 pestañas abiertas, si, por ejemplo, una de las pestañas de trabajo se actualiza, una de las pestañas de carga se desbloquea, pero a veces parece fallar.
Eso es lo esperado y una limitación al no utilizar los flujos de eventos mientras no se usa HTTP / 2 :
Cuando no se usa a través de HTTP / 2 , SSE sufre una limitación en el número máximo de conexiones abiertas, lo que puede ser especialmente doloroso al abrir varias pestañas, ya que el límite es _por navegador_ y se establece en un número muy bajo (6). El problema se ha marcado como "No se solucionará" en Chrome y Firefox . Este límite es por navegador + dominio, lo que significa que puede abrir 6 conexiones SSE en todas las pestañas a
www.example1.com
y otras 6 conexiones SSE awww.example2.com.
(de Stackoverflow ). Cuando se utiliza HTTP / 2, el número máximo de _HTTP streams_ simultáneos se negocia entre el servidor y el cliente (el valor predeterminado es 100).
Tengo problemas para reproducir el problema original porque solo tengo acceso a dos puertas de enlace conectadas en el entorno de ensayo.
Sospecho que esto se debe al hecho de que los encabezados solo se escriben justo antes del primer mensaje en la transmisión. Si no hay mensaje, no hay encabezado y el navegador sigue esperando.
Puedo confirmar esto. Las solicitudes se detendrán si no reciben un encabezado de respuesta. Después de que se abran seis de estas conexiones, todos los XHR posteriores también se detendrán.
Antes del # 2565 esto no era un problema ya que el flujo de eventos siempre enviaba un "mensaje de inicio de flujo" inmediatamente, lo que resultaba en el envío de los encabezados.
Como tal, no lo veo como un problema de interfaz. Lo único que tendría sentido cambiar en la interfaz es asegurarse de que las conexiones de transmisión detenidas se eliminen después de un tiempo determinado.
Entonces, el problema ocurre cuando los flujos de eventos no envían ningún dato. El XHR que realiza la conexión de flujo de eventos solo se resolverá después de que se haya recibido el primer mensaje; de lo contrario, se colgará en el estado
pending
. Una vez que se abren 6 de esas conexiones, todas las demás conexiones también se bloquearán, ya que se ha alcanzado la cantidad máxima de conexiones TCP simultáneas. Entonces, parece que XHR espera algún tipo de reconocimiento del servidor de que se estableció la transmisión.Antes del # 2565 esto no era un problema ya que el flujo de eventos siempre enviaba un "mensaje de inicio de flujo".
Actualmente estoy tratando de averiguar si esto se puede solucionar en el lado de la interfaz y cómo.
En mi experiencia, enviar un "mensaje inicial" no ayuda con este problema. Pruebe usted mismo con la siguiente diferencia:
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 {
Aquí hay un video:
https://youtu.be/0Ir0lakV-Mc
Veo una diferencia.
En master
SIN la diferencia:
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
En master
CON el 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
Tenemos que diferenciar este tema:
Para mitigar 2, el encabezado de respuesta debe enviarse inmediatamente.
Una cosa a tener en cuenta aquí en lo que respecta a la consola, deberíamos considerar también cancelar las solicitudes pendientes. Actualmente, las solicitudes solo se pueden cancelar una vez que se haya establecido la conexión de transmisión.
@kschiffer, ¿ puede darnos pasos para reproducir el problema en 2.?
Actualizo constantemente una sola pestaña de datos de la puerta de enlace y no experimento bloqueos con el último master
(sin parche)
La forma más sencilla es crear una puerta de enlace completamente nueva y desconectada, ya que no enviará ningún mensaje. Luego, navegue a su página de descripción general y regrese a la lista de puertas de enlace seis veces.
Este no es un problema específico de los eventos de la puerta de enlace, sino de todos los flujos de eventos.
Desasignándome ya que este no es un problema que se origina en la Consola.
Cerrado por # 2989
Se introdujo una solución temporal en https://github.com/TheThingsNetwork/lorawan-stack/pull/2989 ; aún no se ha encontrado una solución más sólida.
Entonces, esto es algo en nuestras dependencias (grpc-gateway no descarga correctamente los encabezados) o en nuestro código compartido (tal vez algún middleware grpc o http no vacía los encabezados).
Eliminando la etiqueta bug
porque actualmente no es algo que afecte a nuestros usuarios.
Abra un nuevo problema si todavía hay algo que debe solucionarse.
Comentario más útil
Entonces, esto es algo en nuestras dependencias (grpc-gateway no descarga correctamente los encabezados) o en nuestro código compartido (tal vez algún middleware grpc o http no vacía los encabezados).
Eliminando la etiqueta
bug
porque actualmente no es algo que afecte a nuestros usuarios.