Google App Engine の Datastore 上で動く PStore 互換ライブラリを作ってみた
久しぶりに GAE/JRuby ネタ。 Google App Engine ではローカルファイルの読み書きができないので、 PStore のようにローカルファイルに保存する簡易 DB は使えない。 そこで Datastore 上で動く PStore 互換ライブラリを作ってみた。 GAE/JRuby 上での SPEC ファイルの書き方や、 gem 化の方法が分からないので、とりあえず GitHub ではなく gist にアップしている。
ちょっとしたデータを保存するときなど、わざわざ Datastore を使うのは面倒な場合に使えると思う。
使い方
普通の PStore と同じように使える。
require 'appengine-pstore' db = AppEngine::PStore.new('foo/bar.pstore') db.transaction do |db| db[:somekey] = somevalue puts db[:anotherkey] end
new の引数はファイル名っぽく指定しているけど、ただの ID なので一意であればなんでも OK 。
制限
- 1つのストアに格納できるデータは最大1MBまで。Mershal::dumpでシリアライズされて1行のカラムに格納しているため。
- そのため、Datastoreを使っているのにスケールしない。PStore互換インタフェースを重視している。
- そもそも PStore にあまり大きいデータを格納しないよね?
- 本家の PStore はファイルオープン時に排他ロックをしているけど、 AppEngine::PStore はロックしていない。後勝ちでデータが上書きされる。
- Rails のようにバージョン番号を使った楽観的ロックが必要?
補足
本当は1行に全データをつっこむんじゃなくて、ある EntryGroup の子として1行1データで保存した方がいいのかもしれない。 最初はその方法で作っていたんだけど、同じトランザクション内なのにコミット前のインサートデータが読めなかったりと、既存の PStore との互換性がとれなかったので、いったん断念している。
ソースを見てもらえば分かるけど、ほとんど PStore オリジナルのまま。 ファイルの読み書き部分を Datastore の get/put に書き換えただけ。 でも、シンプルにできたからいいや。