この記事は、Krile Advent Calendar 2日目のやつです。もう心が折れそうです。
さて、Twitterクライアント Krile ですが、このKrileはいくつかの構成要素から成り立ってます。今日はこれらの構成要素をざっくりと紹介します。非常に遺憾ながら、アドベントカレンダーの日付には非常に余裕がありますので、構成要素については徐々に紹介できればいいかなと思います。。。
だいたいこんな感じ:
ツイートの取得と保持
KrileはTwitterクライアントなので、ツイートをTwitterから取得します。取得したツイートはデータベースに保持され、後から抽出や検索を行う際に再利用されます。
データベース周りの実装は StarryEyes.Casket 、Twitter API周りの実装は StarryEyes.Albireo に切り分けられて独立しています。これらのライブラリはインタフェースを提供しますが、このライブラリ自身が自律的に動作を行うわけではありません。
Twitterからのデータ取得
実際にツイートの受信処理を実行する処理は StarryEyes.Models.Receiving に存在します。Krileはユーザが明示的に受信を行う機会は限られており、ほぼ全ての受信がTwitter Streaming APIによってTwitterからプッシュ送信を受けるか、またはタイマーによって自動的に受信を行います。
取得したデータは解析され、タイムラインやデータベースに格納されます。この構造はステージ毎に分離され、パイプラインのように動作します。ツイートを大量に受信した場合でも安定的に動作できるよう、各ステージは非同期的に動作するようになっています。このあたりの構造は別の日にでも。
データベースからのデータ取得・保持
データベースにはツイートやユーザ情報などが含まれます。データベースは多くのタイミングでアクセスするため、高速なディスクを利用するとKrileの動作速度が向上します。たとえば、タイムラインの再構築時だけではなく、誰かからのお気に入り情報を処理したりする場合にもデータベースを参照します。
データベースからのツイート取得にはSQLを利用しますが、これはKrile Queryから自動生成されるようになっています。これについても、もしも時間があれば別の日にまとめます。
ツイートの表示
Krileは一般的なTwitterクライアントですので、グラフィカルなユーザインタフェースを持ちます。ファンキーな見た目をしていますが、Windows Presentation Foundationの力を借りた結果です。
Krileのタイムライン処理には様々な問題があることが知られていますが、このあたりは悪戦苦闘を行っています。また別の日に。
KrileではLivetライブラリの力によりMVVMアーキテクチャを採用できている部分がいくつかあります。非同期で動作している部分が多いKrileにおいて、UIスレッドの存在を意識せずに済んでいる部分が多いのはひとえにLivetの力もあると思います。
オペレーション
非常に一般的なTwitterクライアントであるKrileは、当然のようにツイートの投稿機能を備えています。また、ツイートをお気に入り登録したり、リツイートしたりすることもできます。これらを統合的に管理するために、StarryEyes.Models.Requests にリクエスト キューが存在します。
リクエストキューは、たくさんのリクエストを管理し、それらを非同期的に実行するように構成しています。
なんでこんなことになっているのか
構成要素だけを見ると、非常にシンプルなTwitterクライアントです。しかしその実態は、5万ステップ規模のプログラムです。その実態はどこにあるのでしょうか。
- 非同期的に動作する
- 失敗することが前提である
- ユーザの要求が厳しい
あたりに原因がある気がしています。
非同期的に動作する、ということ
Twitterクライアントは、バックグラウンドのスレッドでツイートを受信し、バックグラウンドで送信するべきです。必然的にマルチスレッドとなります。実際にはこれだけに留まらず、ユーザストリームの受信にはスレッドをひとつ割くことになるでしょうし、過去のツイートの検索は時間がかかるかもしれません。
マルチスレッドプログラミングはその話題だけで世界を作れるほど難しいものとして知られていますし、うかつに切り込むと専門家にkillされるので深くは触れません。闇です。
失敗する、ということ
Twitterへのすべてのリクエストは失敗する可能性があります。もっと言ってしまえば、あらゆる操作は失敗する可能性がありますが、それを考慮しているとプログラムは作れないので、今回はTwitterのリクエストエラーだけに話を絞ります。Twitterへのリクエストがどれくらい失敗するかというと、一時期は「Twitterのリクエストは3回投げてどれかが成功すれば成功」というような状況だったこともありました。これらを適切に処理し、ユーザにどう見せるか、そもそも見せるのか勝手に処理してしまうのか、動作をどの時点まで巻き戻すのか、など話題は尽きません。つまり、これも闇です。
ユーザの要求が厳しい、ということ
krile(クライル)の作者に掘り返されてkrile(クライル)落ちた話してぇ〜〜〜〜〜〜
— あしゅりー (@Asyley_) 2014, 12月 2
krile開発者にツイート掘り返されるたびにPCファン4つとも回転数2000rpmくらい割り増しになるんだけど
— あしゅりー (@Asyley_) 2014, 12月 2
Asyley_の掘り返されに耐えるクライアントは存在するのか?世界は厳しい
まとめ
- Krileの構成要素は意外とシンプル
- Twitterクライアントの開発はつらいことだらけ