mikutterの最新の情報は、mikutter blogに引っ越しました。

2011年3月20日日曜日

#mikutter 0.0.2.12

ピャアアアアアアアアアアwwwwwwww今週リリースしない予定だったけど調子でないから休憩中にバグとか直してたらつい時間をかけすぎてリリースしちゃうwwwwwwww楽しいfixがwwwwwwポポポポーンwwwwwww

よかったこと
mikutterのアイコン完成
実はsoramame_bsclにアイコン作るように去年のはじめにお願いしてて、半年放置されたからヤツの落書きを勝手にアイコンにしてただけだったんですwwwwやっとだよwwwwウェブページのファビコンにもしたよ!やったねたえちゃん!

よくなかったこと
キャッシュがスレッドセーフじゃなかった
ギャアアアアアアアwwwww俺SUGEEEEEEEEEEwwwwwwww

特定条件を満たすつぶやきをふぁぼると落ちる
ひでぇぇぇぇwwwwwww

リスト取得するときにたまに落ちてた
ウワアアアアアアアアアアwwwwwwwもうかくのめんどくせえよおおおおおwwwwww

0.0.2.10以前を使ってる人は、ここのところ全く機能追加できてないお陰で安定性上がってるっぽいので是非バージョンアップしましょう。どうせおちるんだろうけどねwwwwうわあああ死にたくないよおおおwwwwwwwww

2011年3月13日日曜日

#mikutter 0.0.2.11

  • 不具合修正
    • ruby 1.9.2を使用している場合、頻繁にSegmentation Faultが発生していた
      • →rubyか周辺ライブラリのバグを踏んでいたよう
    • notifyのリツイート通知の時に、原文が2回表示されていた
  • 最適化
    • アイコン画像プリフェッチ
殆ど何も変更できてないわけだけれど、これが0.0.3.0になるんじゃないかな、落ちないので。
まあリリースして1日以内にクラッシュするような不具合が見つかるというのを10週連続でやってるんだけどね!

あとレンダリング高速化しようとしてやっぱりやめました。もうちょっと時間をかけて大規模なのをやります今度。

それから、mikutterのサイトのリリースノートやめてこっちにしますんで!だってあのリリースノートRSSにも対応してないただのHTMLなんですもの…(´・ω・`)

2011年3月6日日曜日

#mikutter 0.0.2.10

リリースしました。出先からなので適当に

○プロフィールを開いてすぐに閉じる
とクラッシュする
○Mumbleオブジェクト作成中に落ち ることがある

うけるヾ(@⌒ー⌒@)ノまじこれだけ

あと少しパフォーマンスを上げようとして、ああ、今回もだめだったよ。

そろそろ根本的な解決をしていきたい。mikutterのコードも当社比リファクタリングが進みきれいになったので、マルチスレッドでGtkのレンダリングをしても死なない気がしてきた!ちょっと頑張って見るかな。

あと1.9.2で特定リビジョンがうごかんと言われて試したら、うちでは全バージョンが動かなかった!どうしてこうなった!一応サポートしてるのは1.9.1なんだけど、これもかっこ悪いのでぽちぽちなおしますね…

いつ2次元に旅立っても大丈夫なように@Phenomerさんにコミッタになってもらいました!だけど今クールいくといろいろひどいことされそうなのでもう少し娑婆で頑張る!

2011年3月2日水曜日

streamingプラグインの最適化

streamingプラグインはuserstreamを実現するためだけのプラグイン。(core/addon/streaming.rb)

UserStreamは大量のデータが落ちてくることがしばしばあり、フォローが多いと秒間に数個からヘタをすると数十個のイベントが落ちてくることもあるかも知れない。
(ここでつぶやきではなくイベントと言ってるのは、フォロー関係の変更やDM、favなども落ちてくるので)
mikutterでは、正確にはわからないが、まあフォローが1000を超えていたら絶対に動かないだろう。これは、流速が処理速度を超えるから。
そういう極端に速い環境を切り捨てるのは仕方ないにせよ、全員が定期的に呟いている訳でもないので毎週火曜夜に流速が極端に速くなるということもあるかもしれない。なので、できるだけ対策をしてみようと思った。

これの33行目くらいから変な魔術を使ってる。

# イベントを定義するためメソッド
    def self.define_event(event_name)
      type_strict event_name => tcor(Symbol, String)
      queue = Queue.new
      service = nil
      Thread.new{
        sleep(1) while not service
        loop{
          datum = queue.pop
          yield(service, datum)
          sleep(1) } }
      define_method("event_#{event_name}"){ |json|
        type_strict json => tcor(Array, Hash)
        service ||= @service
        queue << json } end

    # favられイベントの定義
    define_event(:favorite) do |service, json|
      by = service.__send__(:parse_json, json['source'], :user_show)
      to = service.__send__(:parse_json, json['target_object'], :status_show)
      if(by.respond_to?(:first) and to.respond_to?(:first) and to.first.respond_to?(:add_favorited_by))
        to.first.add_favorited_by(by.first, Time.parse(json['created_at'])) end end

event_favoriteメソッドがfavられた時に呼ばれる。こいつが実際のイベントをよんでいるんだけど、いちいちdefine_eventを使って定義している。
このdefine_eventで定義されるevent_favoriteは、Queueに引数をそのまま積んでおしまい。実際には、定義されたと同時に作られた別のスレッドがイベントの処理をする。
これによって、イベント発行にだらだらと時間を使ったりせず、効率的にイベントを発行できるというわけ。
・・・ではなくて、見ていただければわかるとおり、1つキューを消化するごとにsleep(1)を実行しています。
なので、たとえば同時に100favされたとすると、普通の実装だと死ぬほどイベントを発行して、効果音がけたたましく鳴り響いてTLの更新がしばらくおっつかなくなるんですが、この実装によって、最初の1favは即時、残りは99秒かけて1秒間に1つづつイベントが実行される。これによってイベントの実行が遅れる場合が出てくるが、乱発されない限り目立った遅延は起こらない。1つづつしかイベントが発生しないので、処理もすぐに終わるからたいした負荷もかからない。もちろん、フォローなどについても同様。

唯一の例外はつぶやき受信関連。これだけはちょっと違って(詳しくはソースみてくださいそんなにありがたいものじゃないが)、つぶやき関連のイベントは、1回のイベントにいくつでもつぶやきを持たせることができる。なので、1回のループで、キューに溜っているイベントを全て取り出して、一気にイベントを発生させる。
これによって、1秒間に大量のつぶやきを処理する可能性があるけれど、実はイベントの発行って結構非効率なので、10イベンtの発行するよりも1イベントで10ツイートを処理するほうがはるかに経済的。ていうかそんなのが頻繁に起こるならどのみちmikutterつかえない

重要なのは、同じイベントは1秒に1回しか発生しないようになった、ということ。どんな速度でイベントが発生しても、ここでイベントの流量が制限されるようになるわけ。これによって、例えば1分間に100favとかされたときにフリーズすることがなくなりました。

今後の展望(というか実験中のこと)としては、GUIイベントを処理している時など、今やったらユーザの操作に影響が出るぞっていう時にはイベントの発行をさらに1秒遅らせるというの。ウィンドウが完全に応答なしになってるのに次々イベントほりこんでもしゃーないでしょ、という話。TL速い時に起動が数秒遅くなってるんですが、これは起動直後にウィンドウに夥しい量のつぶやきが放り込まれて固まってる間にたくさんイベントが発生しているからに他ならないんですよ。

一方、本当に重くしてる原因は他にあると思うので、そっちを潰すのが先かなぁとも。やはり動きが良いのは良いことです。

2011年2月27日日曜日

#mikutter 0.0.2.9

このようなことを2週前に書いたわけですね

いいこと思いついたコミットしたことをブログでまとめれば毎週一回の更新という今キメた目標を達成できるんじゃないかやっほーい俺ってちょーてんさーい!

で、先週は体調崩してリリースをしなかった、と。
でもそんなの今年初なんだ信じてくれぇ!

ksg
今回の更新について。

効果音の追加

設定→通知から、イベントが発生したときに再生する効果音を設定できます。これに結構前から「フォローされたとき」「リムられたとき」UserStreamに対応した時からは「ふぁぼられたとき」が追加されてました。他のTwitterクライアントのUserStream対応が進まない中、mikutterの対応速度なんと3日だったわけですよすごいでしょ褒めろ
で、今回はfavられた時とReTweetされた時の効果音を追加しましたが、残念ながらReTweet時の通知はまだ実装されておらずリプライ扱いになっていることに気づいたわけだな。ここでもmikutterのカスっぷりが遺憾なく発揮されたわけであります。
更に、@seibe2さんから効果音の提供もいただきました。みんなでmikutterの感染を広げていきましょう!!!!!!!!!!!!!!!!^q^

コンテキストメニュー(右クリックメニュー)の内部仕様

前はコンテキストメニューが独自のフックみたいなのをもってたのを、今回イベントフィルタで実装しなおしました。
これで、前より気楽にコンテキストメニューが拡張できる予定です。更にコンテキストメニューの項目にショートカットキーを割り当てられるようにして、現在ハードコーディングしているショートカットキーの項目をプラグインから気軽に増やすことができるようにする予定です。
ついでに並び替え、罫線の挿入もできるようにするつもりですが、まだこのあたりは終わっておらず、現在コンテキストメニューには罫線が表示されません。あんまりメニューの数多くないので我慢してくだしあ
ここで言っているコンテキストメニューとはつぶやきのそれのことで、タブやPostBoxのそれにも同様のことをしようと思っていますがそれはまた別の話

UserStreamの流速制御機能

ただの最適化です。
今までは、UserStreamに大量のイベントが一気に流れてきた場合、それをいっぺんに処理しようとしてフリーズすることがありました。ここ数日に限って言えば、Twitterが不安定になっており、しばらく止まったと思ったらつぶやきが10件ほど一気に流れてくるというようなことがありました。あと僕最近大量にfavられる嫌がらせ受けてるのでそれもありますね
mikutter開発当初はUserStreamはなく、1つのイベントで複数のつぶやきを扱っていましたが、UserStreamでは1つぶやきに対して1件のイベントを発行していました。そこで、連続してたくさんのイベントが来た場合は一定期間待って、その間に来たつぶやきを全部まとめて1つのイベントとして扱うことで、ピーク時の負荷を下げています。そのせいで1秒程度遅延することがあるけど、まあお得な取引でしょう。
ReTweet、Favoritedもだいたい同様です。

今後

なんか、bit.lyのAPIのバージョンが2から3に上がったみたいですんで対応しましょうか。t.co(だっけ)がTwitterの標準になるとかいってたけどアレは結局どうなったんだっけ。
実はパッチを送ってもらったりしたんだけど、短縮URLの内部処理の変更を検討しているところで、なかなか取り込めない。
あと、リツイートの効果音作ったので、リツイートに対応したいですね。
これを0.0.3に、と言いたいところだがなんか早速死亡フラグが立っててアレ

2011年2月12日土曜日

#mikutter 0.0.2.8

いいこと思いついたコミットしたことをブログでまとめれば毎週一回の更新という今キメた目標を達成できるんじゃないかやっほーい俺ってちょーてんさーい!
(前Tumblrに書いてたのをいつからか完全にすっぽかすようになった)

http://mikutter.hachune.net/

ksg
最近全然ぱっとしたことが出来てないんだけど、これは忙しいからというよりは安定化に舵を切っているからでしてごにょごにょ

どうでもいいけどcore/mui/gtk_mumble.rbはmikutterでは2番目に汚いファイルで、600行くらいあったんだけど、今回ふぁぼられ・被リツイート(まとめてVoteと呼んでる)を扱うGtk::MumbleVoteと、アクティブ(選択)の概念を管理するためのGtk::MumbleSelectに分けました。結果、この2つに関してはユニットテストが書けたし、コード量も結構減ったのでよかった。

同じようにコンテキストメニューのところも分離したあと、ショートカットキーと統合してコンテキストメニューでできることにショートカットキーを割り当てれるようにしよう。もうコンテキストメニューをプラグインから追加する方法はあるので。

2011年2月6日日曜日

複数ファイルからなるプラグイン

今まで、プラグインは、plugin/以下にある*.rbにマッチするファイル名だけになってました。
でもこれでは複雑になったプラグインを複数ファイルに分けたり、画像ファイルなどを入れることができません。
というわけで、最新trunkにこんな仕様変更をしました。(#72
X/というディレクトリがあれば、X/X.rbをrequireする
ディレクトリがつかえるようになれば、いくらでもファイルを入れることができるね!
X/とX.rbが同じ階層にあれば、X.rbが優先されるので注意。

この変更によって、plugin/以下に別のリポジトリからプラグインをチェックアウトして使うということができるようになりました。例えばgithubで公開しているプラグインを入れてそのままつかえる、など。
今のところgithubにdbus-mikutterというのをアップしてます。これはdbusでmikutterのTLの情報が取れます。mikuttering-mode.elというのが同梱されてますがこれを使えばemacsからmikutterをつかえるらしいです。ある人がやってくれました。

これからももっと拡張しやすくしていきたい