huiping192 / HPRTMP

HPRTMP is a Swift library for RTMP streaming, with an easy-to-use API, efficient message handling, and robust error recovery.
MIT License
16 stars 3 forks source link

長時間使っていると、稀にWindow size reachedというログが出続けてそれ以降配信されなくなる #16

Open karino2 opened 3 months ago

karino2 commented 3 months ago

症状

20分程度配信を続けていると、ログに[HPRTMP] Window size reached, waiting for acknowledgement...と表示され続けてそれ以後配信されなくなる。

再現率

4/12回

karino2 commented 3 months ago

ログを挟んで調査した所、NetworkClient.swiftのreceiveDataとresponseReceivedの間にレースコンディションがある模様。

responseReceivedのスレッドをA、receiveDataのスレッドをBとして以下のケースが起こる事を確認

  1. A receiveDataでdataPromiseを設定し、futureResult.get()で待つ
  2. B responseReceivedが呼ばれ、cachedReceivedDataに値を入れてdataPromise.succeedを呼ぶ所でスレッドがサスペンド
  3. A futureResult.get()が起きて結果を返す
  4. A 再びreceiveDataを呼ぶ、この時はcachedReceivedDataがクリアされてなくてこの値を使って結果を返す(これは別のバグ)
  5. A スレッドが再びreceiveDataを呼び、dataPromiseを設定してfutureResult.get()でブロッキングされる
  6. B 2でサスペンドされたresponseRecivedが再開され、cachedReceivedDataとdataPromiseを(誤って)クリア
  7. 以後 BのスレッドでresponseReceivedがいくら呼ばれてもdataPromiseはnilのままなので5のAスレッドは永遠に起きない

dataPromiseとcachedReceivedDataは複数のスレッドからアクセスされているので何らかの保護が必要のようです。 手元でactorを用いるfixを作った所、直っているようでした。のちほどPRを送ります。