はちゅにっき

こっちのブログはまったり更新

ブロック内でのみ有効な Redis のインスタンスを起動したい

最近は Ruby をちょくちょく使っています。

Ruby で Redis を使ったテストを書く場合は fakeredismock_redis を使うのが一般的かと思いますが、ちょっとだけ Fake や Mock ではなく本物の Redis を使いたい時ってありませんか?

例えば Redis やその周辺ライブラリの挙動をちょっと確認したい時とか、手元で Redis の RDB だけを仕込んでおきたい時とか…

ないですね。

と、とにかく、そんな要望が個人的にはあったので、Ruby の勉強を兼ねつつ Redispot という Gem を作ってみました。

github.com

Redispot は引数としてブロックを取り、そのブロック内でのみ有効な Redis のインスタンスを起動します。こんな感じ。

require 'redis'
require 'redispot'

redis = nil

Redispot::Server.new do |connect_info|
  # このブロック内でのみ Redis が起動する
  redis = Redis.new(connect_info)
  redis.ping  # => "PONG"
end

# ブロックの外なので無効
redis.ping  # => raise Errno::ENOENT

上記例ではコンストラクタにブロックを渡して実行していますが、Redispot::Server#start というメソッドもあり、こちらにブロックを渡すこともできます。

server = Redispot::Server.new
server.start do |connect_info|
  # このブロック内でのみ Redis が起動する
  redis = Redis.new(connect_info)
  redis.set("key", "value")
  redis.save
end

server.start do |connect_info|
  # このブロックの Redis は上記とは別の新規インスタンス
  redis = Redis.new(connect_info)
  redis.get("key")  # => nil
end

コンストラクタredis.conf に指定したいパラメータを Hash で渡すことができるので、以下のように指定すれば、Redis の RDB を手元に残すこともできます。

config = {
  dir: File.expand_path('../', __FILE__),
  dbfilename: 'dump.rdb',
}
# Ruby のスクリプトと同じ場所に "dump.rdb" というファイルが残る

Redispot::Server.new(config: config) do |connect_info|
  redis = Redis.new(connect_info)
  redis.set('key', 'value')
  redis.save  # save を忘れると dump.rdb に保存されないよね
end

スポットインスタンスのように「ちょっとだけ使う時のために」ということで Redispot と適当に名前をつけましたが、元ネタは @typester さんが書いて @songmuさんが現在メンテナンスをしている PerlTest::RedisServer というモジュールです。

github.com

ということで、もし、もし、仮にちょっとだけ Redis インスタンスが使いたいなぁ。と思うことがあればご利用ください。