kaeruspoon

お絵描きさん用サイトを作り始める

 ユルさんのためのお絵描きさん用webツール(かえるイメージとでもしておこう)を作り始めました。とりあえず、イラストをアップロードできて、サムネイル一覧表示画面と個別表示画面と最新情報表示用のサイト埋め込みタグ(iframeで)を用意しました。これでお絵描きさんは、自分の既存のサイトに簡単にかえるイメージを導入することができます。
 明日はCSS設定をできる機能とフォルダ機能を実装しようと思います。それくらいで完了かな。

tokyobikeのドロップハンドル化

 ぼくのtokyobikeですが、ドロップハンドルにしたくてうずうずしています。tokyobikeじゃなくて、ぼくがうずうずしています。バーハンドルはのんびり散策するにはいいのだけれど、やっぱり長距離になると手が疲れてくるのです。さいわい、ドロップハンドル自体は安いのですが、STIがちょっと高い。それに、この際フロントをダブルにしようかとも考えたりしたりしなかったり。リアも9速とか10速とかにしたいなあと思ったり思わなかったり。いろいろと考えてしまうのです。

webサーバ Thin を使ってみる

 Mongrelより速いというウワサのThinというwebサーバを会社の同僚の方に教えてもらいました。実際に計測してみるとmongrelより速いそうです。mongrelの開発者がグレてしまったので、Thinを使ってみるのもいいかもしれません。ちょっと試してみました。

 まずはインストール。

sudo gem install thin

 あとはRAILS_ROOTに移動して、

thin start

でOKです。超簡単(デフォルトのポート番号は3000です)。もちろん、RAILS_ENVやポート番号も指定できるしデーモンとして起動することもできます。

thin -p4000 -e production -d

みたいな感じ。デーモンとして起動したときは

thin stop

で停止できます。

いちいち手で入力するのが面倒なので、複数プロセスで起動するthin_clusterを作ってみました。

#!/usr/bin/ruby
require 'yaml'

CONFIG_FILE = "config/thin_cluster.yml"
def error
  puts "thin_cluster config|start|stop [options]"
  exit
end

error if ARGV.size < 1

mode = ARGV.shift
case mode
when "config"
  config = {:env => "development", :port => 3000, :servers => 1}

  if i = ARGV.index("-e")
    config[:env] = ARGV[i + 1]
  end
  if i = ARGV.index("-p")
    config[:port] = ARGV[i + 1].to_i
  end
  if i = ARGV.index("-N")
    config[:servers] = ARGV[i + 1].to_i
  end
  YAML.dump(config, File.open(CONFIG_FILE, "w"))
when "start"
  config = YAML.load_file(CONFIG_FILE)
  config[:servers].times do |i|
    `thin -e #{config[:env]} -p #{config[:port] + i} -P "tmp/pids/thin.#{config[:port] + i}.pid" -d start`
  end
when "stop"
  config = YAML.load_file(CONFIG_FILE)
  config[:servers].times do |i|
    `thin -P "tmp/pids/thin.#{config[:port] + i}.pid" stop`
  end
else
  error
end

thinコマンドをそのまま呼んでるだけの超手抜きですが、まあ自分が使うだけだしこれでいいや。さっそく、kaeruspoonmilookとかえるイメージをthin_clusterで動かしてみます。しばらく様子を見よう。

追記
続きが「Thinサーバーをまた使ってみる」にあります。

svkの使い方まとめ

 ぼくの職場にはときどき声優さんたちがたくさんやってきて、webラジオの収録を行います。となるとちょっと仕事ができる環境ではなくなるので、別のオフィスに移動してプログラミングしています。そうすると開発サーバ上のリポジトリへのコミット(Subversionを使用しています)ができません。というわけで、svkを使ってみることにしました(いまさらだけど)。

まずはsvkのインストール。

sudo aptitude install svk

svkリポジトリを作る(ホームディレクトリに作られます)。

svk depotmap --init

開発サーバのSubversionリポジトリからsvkリポジトリへのミラーリング。
svkのリポジトリは//で表現します。

svk mirror http://develop/svn //svk

開発サーバのSubversionリポジトリとsvkリポジトリの同期処理

svk sync //svk

svkリポジトリから作業用ブランチを作成する。
開発サーバのSubversionリポジトリと同期している//svkに直接コミットすると、開発サーバのSubversionリポジトリにも自動でコミットされてしまうので、作業用ブランチが必要です。

svk copy //svk //work

作業用ブランチからチェックアウト。

svk co //work devel


これで環境構築は完了です。
svkのコマンドはsvnとほとんど一緒なので、いつものようにプログラミングをして作業用ブランチにコミットしていけばOK。これで、飛行機の中でも開発できちゃいます。

開発サーバのSubversionリポジトリから作業用ブランチへの反映方法は以下のとおり。
まずは同期処理。

svk sync //svk

つづいて作業用ブランチへのマージ。

svk smerge -l //svk //work

マージする前に変更点をチェックしたいときは-Cをつかいます。

svk smerge -C //svk //work

マージが完了したら、あとはアップデートするだけ

svk up


作業用ブランチから開発サーバのSubversionリポジトリへの反映方法は以下のとおり。

svk smerge -l //work //svk

これだけで、開発サーバのSubversionリポジトリへも自動でコミットされます。

スノボー旅行記でも書こうかと思ったけど

D.T.T.D. | スキー部
 武石さんが先に書いていました。武石さんが言うほど、ぼくはうまくありません。二十代前半の滑りまくっていたころに比べると全然衰えてるし。
 やっぱり年に一回だけではなかなか上達しませんね。せめて二、三回は行かないと。レンタカーでも借りてユルさんとスキーしに行きたいな。

Hpricot で link タグが勝手に空要素になる

 Hpricotを使っていて、くだらないことでちょっとハマってしまいました。

irb(main):003:0> a = Hpricot("<link>aaaa</link>")
=> #<Hpricot::Doc {emptyelem <link>} "aaaa" {bogusetag </link>}>
irb(main):004:0> a.to_s
=> "<link />aaaa"
irb(main):005:0> (a/:link).inner_html
=> ""

といった具合に、link タグがおかしなことになります。RDFのパースをする処理でこの現象に出会ってしまい、ちょっと時間を浪費してしまいました。
正解は簡単で

irb(main):006:0> b = Hpricot.XML("<link>aaaa</link>")
=> #<Hpricot::Doc {elem <link> "aaaa" </link>}>
irb(main):007:0> b.to_s
=> "<link>aaaa</link>"
irb(main):008:0> (b/:link).inner_html
=> "aaaa"

明示的にXMLだと教えてあげればいいだけでした。

Double Arrayの勉強中

WEB+DB PRESS Vol.42
  • WEB+DB PRESS Vol.42
  • 作者/アーティスト: WEB+DB PRESS編集部
  • 出版社/メーカー: 技術評論社
  • メディア: 大型本
  • 発売日: 2007-12-22

「アルゴリズム超重要」でやったキーワード検索機能ですが、「WEB+DB PRESS Vol.42」にDoubleArrayのお話が載っていたので、ちょっと勉強しています。ぼくが作ったキーワード検索では、TRIEをハッシュ木で実現しているのですが、DoubleArrayではどうなのだろうかと思った次第。
 ところが、検索のアルゴリズムはすごく簡単なのですが、BASEとCHECKの配列を構築するアルゴリズムがよくわからない。ちょっとググってみても特に見つからない。見つかるのは、あらかじめわかっているキーワードをすべて登録する方法。これならちょっと考えれば実装できる。でも、途中でキーワードを追加したり削除したりする方法がむずかしい。違うキーワードなのに、遷移先が衝突しちゃうことがあるけど、このときどうすればいいのか。まあ、のんびりと勉強していこう。

Thinサーバーをまた使ってみる

 Rubyで書かれたwebサーバ Thinも、いつの間にかバージョン0.5.4になっていたので、また試してみることにします。以前、試してみたとき(「webサーバ Thin を使ってみる」)は、HTTPヘッダがおかしなことになって、cookieがうまく働かなかったりしましたが、今回は修正されているみたい。また試してみることにします。
 関係ないけど、Thinのコードネームはおもしろいね。今回はFlying Mustardだそうです。

 spider-manさんがすでに試されていますが、Thinにクラスタ機能が実装されました。が、まだちょっと使いにくそう。なので、以前作ったthin_clusterを改良してみました。

#!/usr/bin/ruby
require 'yaml'

CONFIG_FILE = "config/thin_cluster.yml"
KEY = {"e" => :env, "p" => :port, "s" => :servers}

def error
  puts "thin_cluster config|start|stop [options]"
  exit
end

error if ARGV.size < 1
case ARGV.shift
when "config"
  config = {:env => "development", :port => 3000, :servers => 1}

  work = nil
  ARGV.each do |argv|
    if argv =~ /^\-([eps])(.*)$/
      work = nil
      if $2 && !$2.empty?
        config[KEY[$1]] = $2
      else
        work = $1
      end
    elsif work
      config[KEY[work]] = argv
      work = nil
    end
  end
  YAML.dump(config, File.open(CONFIG_FILE, "w"))
when "start"
  config = YAML.load_file(CONFIG_FILE)
  `thin -e #{config[:env]} -p #{config[:port]} -s #{config[:servers]} -d start`
when "stop"
  config = YAML.load_file(CONFIG_FILE)
  `thin -p #{config[:port]} -s #{config[:servers]} stop`
else
  error
end

 ソースを見れば一目瞭然だろうけど念のため使い方。すべてRAILS_ROOTで実行します。
 まずは設定。

  thin_cluster config -p3000 -e production -s 2

一度設定しておけば、起動するときは

  thin_cluster start

停止するときは

  thin_cluster stop

でOKです。

今週の休日の過ごし方

 「電脳コイル」とか「しゅごキャラ」とか「ケロロ軍曹」とか「ガンダム00」を観たり、かえるイメージをユルさん専用にカスタマイズするために初めてnet/ftpを使ったり、散歩中に新型GT-Rをディーラーで目撃したり、squidをapacheのフロントに置いてみたらRailsの静的ファイルにアクセスできなくて悩んだり、本屋さんで旅雑誌やバイク雑誌を立ち読みしたり、ドトールでコーヒーを飲んだり、UbuntuのGnomeテーマをMacOSXのパクリから黒が渋いMoomex-Ultimatumに変えてみたり、新しいバッグを買ってもらったり、モスバーガーを食べたり、電器屋さんでVAIOtypeSを眺めたり、チャーハンとかコンソメ雑炊を作ったりしてました。

RailsアプリのコードをCapistranoでデプロイする

Capistranoをはじめて使ってみました。
まずはインストール。

sudo gem install capistrano

続いて、RailsアプリにCapistranoを適用します。
RAILS_ROOTディレクトリ上に移動してから

capify .

を実行。
以前は、--apply-toオプションを使っていたようですが、Capistranoのバージョン2からは同オプションが廃止されているので注意です。
そして、作られたconfig/deploy.rbの編集。

set :application, "cap_test"
set :repository,  "http://svn_host/svn/cap_test"
set :user, "tsukasa"
set :password, "tsukasa"
set :deploy_to, "/home/cap_test"

role :app, "cap_test_ap1"

こんな感じ。webサーバとかdbサーバも指定できて、migrationなんかもできちゃうみたい。まだ試してないので、それはまた今度です。

あとはセットアップとアップロードで、コードをデプロイできます。

cap deploy:setup
cap deploy:update_code
cap deploy:symlink

とても簡単だ。symlinkはcurrentという、最新デプロイへのリンクを作ってくれます。
webサーバをリスタートできたり、mongrelと連動もできるみたいです。それもまた今度。

Capistranoとmongrel_clusterを連携させる

 「RailsアプリのコードをCapistranoでデプロイする」の続き。
 capistranoにmongrel_clusterを連携させます。
 config/deploy.rbに以下のコードを追加。

require 'mongrel_cluster/recipes.rb'
set :mongrel_conf, "#{current_path}/config/mongrel_cluster.yml"

これでOK。
cap deploy:setupを実行済みならば、

cap deploy

だけで、subversionからのコードの反映、mongrel_clusterの再起動まで全部やってくれます。すげー便利(いまさら?)。

Capistranoでmigration

Capistranoでは

cap deploy:migrate

を実行すると、config/deploy.rbで

role :db, "db1_server", :primary => true

で指定したサーバ上でmigrationを実行してくれる。

ただ、この場合はDBサーバ上にもコードをデプロイする必要があって、あまりうれしくない感じだ。
この場合、

role :db, "ap1_server", :primary => true

というようにAPサーバを:dbロールに指定してあげると、database.ymlの設定にしたがってDBサーバにmigrationをしてくれる。これなら、DBサーバにコードをデプロイする必要はない。

でも、こういう使い方でいいのかなあ。よくわからない。