at posts/single.html

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 に書き換えただけ。 でも、シンプルにできたからいいや。