2012年6月2日土曜日

まだまだ Skype API で闘えます

今日は Skype API についての個人的な所感についてメモしておこうと思ったので、だらだらと書いてみます。ああ、ええと、Skype APIの利用シーンとしてはサーバプロセスのような使い方を想定します。ボットとかふくむ感じね。

  1. プロセス間通信は死ぬ
  2. Skypeクライアントは死ぬ
  3. X11は死ぬ
大きく上の要点について書くことにする。基本的には安定化のチューニングを行うプロセスについての解説ね。



1. プロセス間通信は死ぬ


まあ、よく死にます。Skype APIを使ったシステムを作ったときにあたる最初の壁はたぶんこれ。Skype API は dbus 経由とかでSkypeクライアント通信することになるんですが、こいつがとにかくよく死ぬ。
これはそういうもんなんだ、とあきらめて dbus を叩くプロセスとビジネスロジックのプロセスを分けろ。dbus を叩くプロセスは死んでも表からは死んだようにみえないようにハンドリングして知らん顔しつつ、裏では殺して新しいプロセスを作る。注意点として、ここでは fork とか使ってもムダなことが多い。キレイなプロセスを用意しなおす。表のプロセスとのやりとりをうまく行えば外からはいかにもシステムが生き続けているようにみせることはできます。


2. Skypeクライアントは死ぬ


上の壁を乗り越えて、次にあたる壁がおそらくこれ。Skypeクライアントが死ぬ。
あー、まずあれなんですけど、ボットとかのシステムで使うためのSkypeクライアントでログインして履歴とってるのはすでにSkypeクライアント様に死んで下さいって言ってるようなもんなので履歴機能は切りましょう。履歴なんてものは他のクライアントからリレーすればいいんです。わざわざSkype APIを使ったシステムに不安定な責務を負わせてはいけない。
それでも死ぬ。履歴以外にどんなデータが蓄積されているのかはよくわからんが、Skype APIを使わずに、安定した環境で起動しっぱなしにして送受信するだけでもSkypeクライアントというのはメモリを食い尽くしてヤバイことになるんですな。メモリリークだと思うんだが、内部がわからんのでとりあえず殺す方法を考える。
これは思ったほど難しいことではなくて、 dbus 経由で通信するプロセス側のタイムアウトを伸ばしてそのタイムアウトまでに再起動するというスクリプトを書いてSkypeクライアントを定期的に殺しては新しいSkypeクライアントのプロセスを生成ってことをしてあげればいい。
基本的には kill でいいんだが、それでも死なないことがあるので、kill のあとに死んでなかったらきっちりKILLシグナルで殺す。さもなくば、滞留したプロセスがSkypeクライアントの起動を阻む形になり、通信はうまくいかないわ、同じユーザで複数プロセスを起動するなだの文句を言われ続け、いつの間にか「起動するな」ダイアログで埋め尽くされるので注意が必要。
まとめると、Skypeクライアントは複雑な状態マシンになってるみたいなので、定期的に状態を初期状態にすることで安定を保つようにしろ。幸運にもSkypeクライアントは殺してから起動すれば前回起動していた最後の時点からの通信を受信するので、タイムアウトまでに復帰させれば何ごともなかったかのように振る舞うようにシステムを構成できる。


3. X11は死ぬ


大量のメッセージングを行うにつれ、Skypeクライアントを再起動させる勘所というか、頻度をどんどん短くしないといけなくなります。このあたりで薄々とSkype APIというものの使い方を間違えてるんじゃないかと思わないでもないが、ガンガン殺してガンガン新しいSkypeクライアントのプロセスを生成しましょう。やればできるもんだなぁ、くらいには通信してくれます。
そうすると最後にやってくるのがこれですね。
なんとSkypeクライアントがX11を巻き込んで死ぬ。
詳しい検証はしてないのですが、 Xvfb とか使っても同じだと思われます。大量のメッセージングでも安定するようにチューニングしていくと、だいたいがX11の死亡というところまでいきつきます。
しかし、安心して下さい。X11を殺すには相当量のメッセージングを行う必要があります。おそらく、X11が死ぬころにはあなたは果たしてこれは dbus 経由の弱っちいSkype APIという基盤でやりとりする情報量なのだろうか、と疑問に思っていることでしょう。


まとめ


SkypeクライアントがX11を巻き込んで死ぬまではSkype APIで闘えます。
追伸。X11を殺すほどよりも斜め上をいく量のメッセージングを行う方法についてもいくつか方法がありますので、需要があれば続編についても書こうかな、と思います。