Sinatra with Delayed Job on PostgreSQLがローカル(OS X Lion)で動きました。以下、備忘録です。
概要
Sinatra上のウェブアプリケーションにバックグラウンドジョブを実装しました。
バックグランドプロセスにはRailsプラグインとして有名なDelayed Job、バックエンド(ジョブキュー)にはActive Record、データベースにはPostgreSQLを採用しました。
データベースPostgreSQLの準備
PostgreSQLはオープンソースのデータベースです。herokuがウェブアプリケーションに提供するデータベースサービスにも使われています。heroku上へのディプロイが目的なので最初からPostgreSQLを使うことにしました。
1. MacPortsからインストール
Lion(もしくはXcode for Lion)にはデフォルトでPostpreSQLがプレインストールされているようです。知らなかったので、MacPortsからインストールしました。(これがトラブルの元になりました。)
sudo port install postgresql90 postgresql90-server
インストールするとその後必要な手順も出力されますので、そのまま実行してください。(データベース用ディレクトリの作成とデーモン起動)
sudo port load postgresql90-server sudo mkdir -p /opt/local/var/db/postgresql90/defaultdb sudo chown postgres:postgres /opt/local/var/db/postgresql90/defaultdb sudo su postgres -c '/opt/local/lib/postgresql90/bin/initdb -D /opt/local/var/db/postgresql90/defaultdb'
2. データベース用アカウントのパスワード変更
postgresというユーザーアカウントが作成されるので、パスワードを変更しておきましょう。
3. PATHの設定
.profileにてPATHの先頭に/opt/local/lib/postgresql90/binを追加します。
PATHを追加しないと、以下の作業で前述のプレインストールのPostpreSQLコマンドが起動して動かず悩みます。また、RubyのPostgreSQL用アダプタpg gemをインストールする際にもエラーの元になります。
(ここで一度再起動が必要かもしれません。)
4. データベースユーザーの作成
su postgres createuser
createuserの後、プロンプトが出るので質問に答えていきます。
使い分けがわからないので、ユーザー名はOSのアカウント名を一緒にしておきました。
データベースを作成できるように設定。
以上でデータベースのインストール完了です。
SinatraでDelayed Jobを使う
Railsでマイグレーションファイルを用意する
SinataでActive Recordを使うのにマイグレーションファイル生成などsinatra-activerecordパッケージがありますのが、 sinatra/activerecord/rakeはほとんど空っぽのマイグレーションファイルしか作ってくれませんでした。delayed_jobを指定する方法がよくわかりませんでした。なので、Railsで生成してコピーしました。
後で知ったDelayed Job (DJ)の記事に従って作るほうが筋が良さそうです。
1. Railsで新しいアプリケーションを生成します。
rails new foo--database=postgresql
2. Gemfileにgem 'delayed_job'の一行を追加して、インストールします。
bundle install
3. マイグレーションファイルを生成します。
ruby1.9 script/rails generate delayed_job
アプリケーションfooの役割はここまでです。
アプリケーション用データベースを作成する
createdb <database name>
Sinatraアプリケーションを変更する
1. アプリケーションfooのconfig/database.ymlをコピーして、データベース名など必要な修正をします。
2. アプリケーションfooのdb/migrate以下をコピーします。
3. Gemfileに以下を追加し、インストール(bundle install)を実行します。
gem 'pg' gem 'activerecord' gem 'logger' gem 'delayed_job'
pgはRubyのPostgreSQLアダプタです。ググるとpostgresやpostgres-prも目につきますがpgを使います。
4. Rakefileを作成します。
require 'configureを含むファイルのベース名' require 'delayed/tasks' task :environment namespace :db do desc "Migrate the database" task :migrate => :environment do ActiveRecord::Base.logger = Logger.new(STDOUT) ActiveRecord::Migration.verbose = true ActiveRecord::Migrator.migrate("db/migrate") end end
私の場合、configureはwebプロセス本体に入れました。
5. configureを記述します。
webプロセスのファイルの先頭(requireの後)に以下を追加します。
configure do config = YAML::load(File.open('config/database.yml')) environment = Sinatra::Application.environment.to_s ActiveRecord::Base.logger = Logger.new(STDOUT) ActiveRecord::Base.establish_connection(config[environment]) Delayed::Worker.guess_backend end
最後の行はDelayed::Workerの初期設定です。最小限、.guess_backendは入れてください。これでDelayed::Jobが動的に定義されます。
6. データベースのマイグレーションを実行します。
rake db:migrate
これで出来上がりです。
アプリケーションを実行する
必要なコーディングが終わったらアプリケーションを実行します。
webプロセスを実行する前にworkerプロセスを立ち上げる必要があるので、以下のようにします。
rake jobs:work rackup
大勢の方がトライしてノウハウを書かれていますが、断片的で苦労しました。私の備忘録も断片的ですね…