Twilio Clientのコントリビューターになったので経緯の紹介


こんにちは、@24guchiaです。

今年(2019年)の頭に、Twilio Clientの不具合を見つけ、
修正依頼をKDDIウェブコミュニケーションズ社に依頼しました。
その後、バグは無事修正され、しかもその依頼がバグ改修の助けになったとのことで、
Twilio ClientのChangelogに名前を残してもらえることになりました!

https://www.twilio.com/docs/voice/client/javascript/changelog#172-may-3-2019

他のChangelogを見てもらえば分かる通り、
このような記載はなく、貢献が認められ技術者として嬉しい限りです。

コントリビューターとしては僕と、一緒に保守をしてくれている
フリーランスの土橋さんです。
バグ発見と原因究明を僕、コード改修を土橋さんという感じでやりました。

せっかくなので、どのようなことをしたか経緯をまとめます。
バグ改修を行うことで、貢献が認められこともあるので、
ぜひみなさんもバグを見つけたら改修依頼をしましょう。

当時の環境

下記環境でテストしていました。

  • Chrome M72 beta
  • Twilio Client v.1.4.35
  • 内製したChrome ExtensionでTwilio Clientを読み込む

ChromeがM71→72になるにあたり、
SDPのデフォルト記述法がPlan BからUnified Planに変わる
とのことで、Twilio Clientもそれに追従するため、
バージョンアップを控えていました。

ClientはTwilio日本ユーザの間では、
自動アップデートせず、実際に使用する環境でテストして、
問題がないことを確認してからClientをバージョンアップすることが通説になっています。
というのも、こういうバグが発生し、突然動かなくなることがあるからです。
Clientに限らず、この手のものは手動アップデートをおすすめします。

そのため、M72ベータにバージョンアップしたTwilio Clientを適用し、
疎通テストを行ったところ、なんと音が出なくなるバグを見つけてしまいました。

Changelogに載るまでの経緯

該当のバグはTwilio Clientを更新せずに、
数十回、連続で通話すると通話の音が聞こえなくなるという
致命的なものでした。
しかし、Twilioの日本ユーザグループのSlackで聞いても、
そんなことあるんですか?という感じで、解決しませんでした。

そのため、自分たちで調査することを決めました。

原因を探る

ChromeでWebRTCプロダクトを開発している人なら必ず見る、
webrtc-internalsとmedia-internalsを見ていました。
以前使用していたバージョンとの挙動を確認しつつ、
media-internalsを見ていたところ挙動に違いを見つけました。

新しいバージョンで電話を受けると、
複数のMediaオブジェクトがポーズ状態で残っていました。
以前のバージョンではポーズではなく、破棄されていました。

そのため、Mediaオブジェクトの解放タイミングに問題があると推定し、
再現方法を探ることにしました。

当時のメモによると、受電すると3つMediaオブジェクトが生成され、
約15通話で音が出なくなるため、だいたい45個のMediaオブジェクトが残ると、
音声再生に不具合が発生するようだと書いてありました。

問題の切り分け

原因はわかりましたが、問題の発生箇所は
Twilio ClientなのかChromeなのか、この時点では断定できていません。

そこでかんたんにMediaオブジェクトを増やせる、
みんな大好きYoutubeをたくさん開くことで
再現するかを試しました。
ChromeでYoutubeの適当な動画を再生すると、
1つMediaオブジェクトが生成されることが
media-internalsの挙動を見てわかりました。

上に45個のMediaオブジェクトで音声再生に不具合が発生しそう
と書きましたが、正確な数は不明です。
そこで、一気に同じ動画を100タブ分、開いてみたところ、
見事に音声再生で不具合が発生しました!
Youtubeでこんな不具合が起きるんですよ。
このとき、初めて知りました。

ソースコードの改修

Githubに土橋さんが改修したコードが残っていました。
https://github.com/tsuchihashi-lvgs/tmp-bugfix-twilio-sdk#wip%E5%AF%BE%E5%BF%9C%E6%96%B9%E6%B3%95

audioElementにオブジェクトが残りっぱなしになっているようで、
その変数に対してnullを代入することで明示的に破棄しています。

僕が推定しているバグ原因とも一致する改修方法でしたし、
実際に改修後のソースコードを使うとバグが再現しなくなりました。

KDDIウェブコミュニケーションズ社への報告

元々、問題発生時点から何度もやり取りをしていたので、
原因と改修コードを提供したあとはスムーズでした。

その後、僕による不具合の調査と、土橋さんのコードがTwilio Clientの改修に取り入れられ、
謝辞がChangelogに入ったと報告がありました。
同時に、僕の名前がなく土橋さんの名前もTsuchihashi-lvgsとGithubの
アカウント名だったので、担当者からTwilio社に正式な名前で書くよう
依頼をしますと提案されました。
本当にありがとうございます。

そして何度かの依頼を経て、無事に現在のChangelogになりました。

なんでこの問題を発見したのか?

Twilio Clientの使い方が、他の会社と違うことが大きな理由と考えています。

Twilio Clientの永続化

環境に書いた通り、Chrome Extension内でTwilio Clientを動かしています。
Extensionはバックグラウンドでプロセスを永続化できるため、
特定のページを開く必要がなく、ExtensionでTwilioへのログインを最初にし、
Chromeさえ開いていれば、ずっとTwilio Clientが動き続きます。

ただ、他社のTwilioの使い方を聞くと、
特定のページでTwilio Clientを動かしているという使い方が多いようです。

そのため、Extensionをバックグラウンドで動かし続け、
Twilio Clientを更新しないことで、
Mediaオブジェクトの解放頻度が他社と比べて非常に低い特徴がありました。
この特徴により、問題の発見をすることができました。

デバッグ中も音が出なくなった後、
Twilio Clientを更新することで音が出なくなる問題が解消されることが
確認できていたため、使い方が独特なんだなと思います。

まとめ

OSSコミットをしたことがないので、
個人的にはとても貴重な体験でした。
ちゃんとコントリビューターとして名前が残せ、
最近Twilio Championにもなったので、
これでまたTwilioチョットデキル人として実績が残せて嬉しいです。

何らかのトランスパイラでコンパイルして、
めちゃくちゃ読みづらいJavaScriptコードを読み切って、
バグ改修した土橋さんもすごかった。
結果だけ見るとかんたんな改修に見えますが、
何度も地道なデバッグをした結果だと思います。
また、Changelogにちゃんと名前を載せるよう何度も依頼してくれた
KDDIウェブコミュニケーションズ社の担当者にも感謝してます。

というわけでバグを見つけたら、
徹底的にデバッグして、原因究明し、コード改修案を出せば、
誰でもコントリビューターになれることがわかりました。
みなさんもバグを見つけたら、ぜひ挑戦してください。