パラボラアンテナと星の日記

あることないこと

rubotyで、redisを使わないでみる

いつも実りのないエントリですが、 今回は 本当に実りがないので、ご理解ください。

rubotyは、ruboty作者の方が作ったruboty-redisがべんりです。

今回は、これを使わないとどうなるか?ということを考えてみました。

Rubotyのデータ永続化

Rubotyにおけるデータの永続化は、READMEに書いてあるとおり、Ruboty::Brainsというモジュールが担当しています。 ruboty-redis以外のbrainも可能なようにプラガブルになっています。

ちなみにGemfileにruboty-redisを書かないと、 Ruboty::Brains::Memoryというクラスが効くようになり、プロセスの中でデータを保持するようになります。

lib/ruboty/brains/memory.rbはとてもシンプルで、こんな感じです。

ruboty/memory.rb at master · r7kamura/ruboty · GitHub

module Ruboty
  module Brains
    class Memory < Base
      def data
        @data ||= {}
      end
    end
  end
end

ただしこれはもちろん、一度プロセスが死ぬと、同時にデータは失われます。

試しにruboty-templateのGemfileからruboty-redisを消し、

- gem 'ruboty-redis'

以下のようにデータを登録した後にrubotyを再起動してみる、と、 データが失われていることがわかります。

$ bundle exec ruboty
Type `exit` or `quit` to end the session.
> ruboty add job "0 * * * *" 0-hun-desu!
Job 255 created
> ruboty list jobs
  255: "0 * * * *" 0-hun-desu!
> exit # 一度終了する

$ bundle exec ruboty # 再度起動
Type `exit` or `quit` to end the session.
> ruboty list jobs # 覚えてるかチェック
Job not found # 覚えてない!

諸行無常感がすごいですね。

Brainを自作してみる

そこで、Ruboty::Brainsをredis以外で自作してみることにします。 データストアは何にしましょうか。 MySQLとかだと面白くなさそうです。 rubyistなら、そうですね、 ご存知PStore ですね。

Rubyist Magazine - 標準添付ライブラリ紹介 【第 9 回】 PStore

lib/pstore.rbは前世紀からrubyに存在します。 PStoreについてご存じないようでしたら、適当にググっていただけると出てくると思います。

要は、「Ruby のオブジェクトを外部ファイルに保存できる」ライブラリですね。

PStoreでRuboty::Brainsをつくった

やりました。できました。pstoreのとこ以外はほぼruboty-redisパクリいいとこ取りでござる。

hoshinotsuyoshi/ruboty-local_pstore · GitHub

ほんとうに永続化できてるの。

Gemfileをこう書いて

- gem 'ruboty-redis'
+ gem 'ruboty-local_pstore'

一度プロセスを終了してもデータが消えないか、試してみます

$ bundle exec ruboty
Type `exit` or `quit` to end the session.
> ruboty add job "0 * * * *" 0-hun-desu!
Job 9527 created
> ruboty list jobs
 9527: "0 * * * *" 0-hun-desu!
> exit # 一度終了する

$ bundle exec ruboty # 再度起動
Type `exit` or `quit` to end the session.
> ruboty list jobs # 覚えてるかチェック
 9527: "0 * * * *" 0-hun-desu! # 覚えてる!
> 

できてますね! やった!

それべんりなの

作るまえからわかっていたのですが、 実はぜんぜんべんりではありません。

というのもherokuで使おうとすると(おそらく一番あるユースケースですね) 、 少なくとも

  • heroku restart時
  • git push heroku master時(デプロイ時)

の際にデータが消えるからです。。 これは内部的には起動するコンテナが変わってしまい、データを蓄積したファイルが消えてしまうことによるものです

今回作ったものを表にして比較すると

brain name データストア場所 (PCとかで)bundle exec ruboty終了時 (herokuで)デプロイ時
Ruboty::Brains::Memory プロセスの中のメモリ 消える 消える
Ruboty::Brains::LocalPStore(今回作ったやつ) ファイル 消えない 消える
Ruboty::Brains::Redis Redis 消えない 消えない

という感じです。

また変なgemをつくってしまった。。

変な表まで作ってしまった。。

Brainsの勉強になったので、よしとします

次は

もうちょっとおもしろいデータストア考えます