問題の詳細
元のエラーは、投稿ボタンを押しても失敗し、しかも何秒か後にエラー通知+再投稿の確認のためのダイアログウィンドウがポップアップ表示される、というもの。再投稿すると成功するものの、ポップアップまでの何秒かが絶妙にストレスフルでした。
OpenTween渾身のメタエラー pic.twitter.com/NmLBJ6ULsE
— もっこす@呉鎮 (@moccos) 2014, 8月 31
エラー内容の日本語が謎ですが、原文のThe underlying connection was closed: A connection that was expected to be kept alive was closed by the server に対応するようです。(参考リンク)修正内容
diffにある通り、HTTP層 (Connectionヘッダ)のKeepAliveを無効にしました。Twitter APIのKeepAliveについては、検索すると、2011年のTwitter Development Talk groupへのポストが引っかかります。KeepAliveがサーバー側で有効の場合は、Responseを返した後もサーバー側がTCP接続を切らず保持します。そんなリソースを食う挙動を、膨大なユーザーからの投稿があるTwitterでやるわけなかろう、というのが先のリンク先の会話。
KeepAliceが無効なサーバーは用が済んだら即Closeしてくるはずなので、レスポンスの悪い環境で、問題が顕在化したものだと思われます。我が家は夜間の回線品質に明確に問題を抱えているOCNなので、見事にその時間だけエラーが出ました。
エラー内容でも、捕まえた例外(pull reqのスクショ参照)でもKeepAlive関係であることが明らかであり、手元ではエラーが一切発生しなくなったため、この修正でいけるでしょう!と思いつつも、 環境によって再現性の違うエラーに対する対処は不安なので、直した翌日にフォロワーのOpenTweenユーザーの皆様に手元の修正版バイナリを試していただき、エラーが解消したようなのでpull requestしました。
LOC
修正した日+翌日の検証依頼で2日使ったので、このパッチの効率をSLOC(Source line of code)で表すと 1SLOC/Dayです。同じ内容を二箇所に書いているので、さらに半分かも。ネットワーク周りの修正って、ステートを持ち自律動作する複数の(最低限自分と相手の)プロトコルスタック相手なことが基本で、大山鳴動して最終結論はパラメータ1個修正みたいな話が時々ありますよね。いつぞや仕事でも、担当外部分のパフォーマンス問題解決のために、プロファイル→ソース解読→修正→プロファイル→コミットのために、確か2日かけて1行足しました。生産性がSLOC評価だと死んじゃいます(゚Д゚)
若干の愚痴
原因がわかったら一瞬で修正完了すべきものが、一瞬では終わらなかった原因が大きく2つありまして…- catchした例外をstringに変換して渡している
- 13000行のTween.csにかなりの機能が入っている
(余談: Go言語はちょっと触っただけなんですが、String() stringしかないErrorインターフェイスって、素人が作ったら同様のstringly typedシステムになりそうな…?)
Tween.csについては、何かあるたびにネタにしてしまうのですが(すいません)
13000行あるTween.csの3000行目あたりなので誰か直そう (まだ健在かこの構造
— もっこす@呉鎮 (@moccos) 2014, 8月 31
関数辿ったり戻ったりしながら修正するときに、同一ファイルだと不便なんです。何か直したときに全てTween.csへの変更になるので、修正箇所がわかりづらいとか、容易に修正がコンフリクトするとか、そういう問題も勿論あり。気合の入った構造改革せずとも、とりあえずpartialで分けるとこからでも、なんとかなりませんかねー。実は以前弄ったときに手元でやったのですが、こんなでかい変更プルリクされてもつらいよなーと思ってそのまま捨ててしまいました。Tween.csへの変更は基本的にコンフリクトする、という鶏・卵問題でもあります。
オープンソースとクローズドソースとの関係
OpenTween派生のクライアントで同じ問題が出ているものがあれば、同じ修正で直ると思われます。本家Tweenは状況知らないけども、もし同じ症状なら同様に直るのでは。OpenTween→Tweenへの取り込みは可能で逆は不可って状況、心理的に微妙ではありますが…
09/05追記:あっさりTweenに取り込まれた模様。
0 件のコメント:
コメントを投稿