https://github.com/TheThingsNetwork/lorawan-stack/pull/2565以降、コンソールでクリックした後、イベントはコンソールブロックでストリーミングされます。
ある時点で、コンソールはロードを続けます。 これは、 /api/v3/events
リクエストが閉じられていないため、「開いている接続が多すぎる」ことが原因のようです。
コンソールは応答性を維持する必要があります。
現在のmaster
ブランチ3df51cd750f57b37c3acffc28b417441babdbf30に基づいてビルドします(コンソールに表示される3.8.5には注意を払わないでください)
これは、ヘッダーがストリームの最初のメッセージの直前にのみ書き込まれるという事実が原因であると思われます。 メッセージがない場合、ヘッダーはなく、ブラウザは待機し続けます。
したがって、調査するために、次のことをお勧めします。
複製手順を試してください
Firefoxコンソールでは、開いているタブが6つある場合(たとえば、作業中のタブの1つが更新された場合)、読み込み中のタブの1つがブロック解除されますが、失敗することがあります。
いずれにせよ、私は開始/終了メッセージを送信しようとしましたが、それは何も変わりませんでした-6つのタブがある後もハングします。
注:すべてのタブはゲートウェイのデータビューにあります(2つの異なるタブ)
@kschiffer何かアイデアはありますか?
Firefoxコンソールでは、開いているタブが6つある場合(たとえば、作業中のタブの1つが更新された場合)、読み込み中のタブの1つがブロック解除されますが、失敗することがあります。
これは予想されることであり、HTTP / 2を使用していないときにイベントストリームをアンシングするという制限があります。
HTTP / 2でChromeとFirefoxで「修正されません」とマークされています。 この制限はブラウザ+ドメインごとであるため、すべてのタブで6つのSSE接続を
www.example1.com
開き、さらに6つのSSE接続をwww.example2.com.
開くことができます(
ステージング環境で接続されている2つのゲートウェイにしかアクセスできないため、元の問題を再現するのに問題があります。
これは、ヘッダーがストリームの最初のメッセージの直前にのみ書き込まれるという事実が原因であると思われます。 メッセージがない場合、ヘッダーはなく、ブラウザは待機し続けます。
確認できます。 応答ヘッダーを取得しない場合、要求は停止します。 このような接続が6つ開かれると、後続のすべてのXHRも停止します。
#2565より前は、イベントストリームは常に「ストリーム開始メッセージ」をすぐに送信し、その結果ヘッダーが送信されるため、これは問題ではありませんでした。
そのため、フロントエンドの問題とは考えていません。 フロントエンドで変更するのが理にかなっている唯一のことは、停止したストリーム接続が特定の時間の後に強制終了されることを確認することです。
したがって、この問題は、イベントストリームがデータを送信しない場合に発生します。 イベントストリーム接続を実行するXHRは、最初のメッセージが受信された後にのみ解決されます。それ以外の場合は、
pending
状態でハングします。 これらの接続のうち6つが開かれると、同時TCP接続の最大数に達したため、他のすべての接続もハングします。 したがって、XHRは、ストリームが確立されたことをサーバーから何らかの確認応答を期待しているように見えます。#2565より前は、イベントストリームは常に「ストリーム開始メッセージ」を送信するため、これは問題ではありませんでした。
私は現在、これをフロントエンド側で修正できるかどうか、またどのように修正できるかを調べようとしています。
私の経験では、「初期メッセージ」を送信してもこの問題は解決しません。 次の差分を試してみてください。
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 {
これがビデオです:
https://youtu.be/0Ir0lakV-Mc
違いはわかります。
差分なしのmaster
:
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
master
で差分を使用します。
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
この問題を区別する必要があります。
2を軽減するには、応答ヘッダーをすぐに送信する必要があります。
コンソールに関する限り、ここで注意すべきことの1つは、保留中のリクエストのキャンセルも検討する必要があります。 現在、リクエストは、ストリーム接続が確立された後でのみキャンセルできます。
@ kschiffer2で問題を再現する手順を教えてください。
私は常に単一のゲートウェイデータタブを更新しており、最新のmaster
(パッチなし)でハングすることはありません
最も簡単な方法は、メッセージを送信しないため、完全に新しい未接続のゲートウェイを作成することです。 次に、概要ページに移動し、ゲートウェイリストに6回戻ります。
これはゲートウェイイベントに固有の問題ではありませんが、ちなみにすべてのイベントストリームです。
これはコンソールに起因する問題ではないため、割り当てを解除します。
#2989で閉鎖
一時的な解決策がhttps://github.com/TheThingsNetwork/lorawan-stack/pull/2989で紹介されました-より堅牢な解決策はまだ見つかりません。
したがって、これは依存関係(grpc-gatewayがヘッダーを適切にフラッシュしない)または共有コード(おそらく一部のgrpcまたはhttpミドルウェアがヘッダーをフラッシュしない)のいずれかにあります。
bug
ラベルは現在ユーザーに影響を与えるものではないため、削除します。
対処する必要のあることがまだある場合は、新しい問題を開いてください。
最も参考になるコメント
したがって、これは依存関係(grpc-gatewayがヘッダーを適切にフラッシュしない)または共有コード(おそらく一部のgrpcまたはhttpミドルウェアがヘッダーをフラッシュしない)のいずれかにあります。
bug
ラベルは現在ユーザーに影響を与えるものではないため、削除します。