EC2のサーバ上でruby-1.8.x系で動作しているpassenger(aka mod_rails) と平行して、ruby-1.9.1を動かす環境を用意するために色々と試行錯誤を繰り返していたのですが、ひとまず良さそうな構成に落ち着いたのでメモしておきます。

構成

入り口から順に並べるとこんな感じです。

  • apache2 (:80)
  • mod_proxy_balancer (:80 -> :4000)
  • swiftiply (:4000 <- :30000)
  • merb cluster with SwiftipliedMongrel adapter (:30000)

apache2はpassengerを使っているので外せないとして、 ruby-1.9.1で動かすサービスはmod_proxy_balancerを使う事にしました。 最初はバックエンドに直接merb clusterを当てていたのですが、 現状のmerb clusterにはgraceful reloadする機能が無いようだったので、 間になにか挟む事にしました。

そこで、以前から目を付けていた Swiftiply を試す事にしました。 Swiftiplyはとても面白い設計のウェブサーバで、そのへんは rakutoさんの記事 「[Rails] Swiftiplyのアーキテクチャとベンチマーク」 を読むのがわかりやすいでしょう。

merbはbuilt-inでSwiftiply用のアダプター(SwiftipliedMongrel adapter)を備えているので、Swiftiplyを起動する設定をおこなえば、使うのはわりと簡単です。

しかし、例によってswiftiplyが依存しているeventmachineがruby-1.9.1 でインストール出来なかったので、原因を調査。 単純にテストの実行だけがうまく動いてないようだったので、テスト無しでインストールしました。

あとは、swiftiplyの起動スクリプトを用意。

/etc/init.d/swiftiply

   1  #!/usr/bin/env ruby
   2  
   3  PID = "/var/run/swiftiply.pid"
   4  
   5  case ARGV[0]
   6  when 'start'
   7    if File.exist?(PID)
   8      puts "swiftiply is already started."
   9      exit 1
  10    end
  11    print "Starting swiftiply: "
  12    pid = fork do
  13      Process.setsid
  14      Process.exec "swiftiply", "-c", "/etc/swiftiply.yml"
  15    end
  16    begin
  17      open(PID, "w"){|file| file.write pid}
  18      puts "done"
  19    rescue Exception => e
  20      puts e.message
  21      Process.kill 9, pid
  22    end
  23  when 'stop'
  24    print "Stopping swiftiply: "
  25    begin
  26      pid = open(PID).read.to_i
  27      File.unlink PID
  28      Process.kill 9, pid
  29      puts "done"
  30    rescue Exception => e
  31      puts e.message
  32    end
  33  when 'restart'
  34    system $0, 'stop'
  35    system $0, 'start'
  36  else
  37    puts "usage: {start|stop|restart}"
  38  end

アプリケーションの起動、停止は以下のようにおこないます。

   1  cd #{current_path}; #{merb} -K all
   2  cd #{current_path}; #{merb} -e production -a swift -c 1 -p 30000

これで動きますが、プロセスが死んだりすると不安なので、 monitを使って死活管理をおこなうようにします。

/etc/monit/monitrc

   1  check process swiftiply
   2    with pidfile /var/run/swiftiply.pid
   3    group root
   4    start program = "/etc/init.d/swiftiply start"
   5    stop program = "/etc/init.d/swiftiply stop"
   6    if failed port 4000 then restart
   7    if 5 restarts within 5 cycles then timeout
   8  
   9  check process merbist
  10    with pidfile /mnt/app/merbist/current/log/merb.30000.pid
  11    group root
  12    start program = "/mnt/app/merbist/shared/script/start"
  13      as uid app and gid app
  14    stop program = "/mnt/app/merbist/shared/script/stop"
  15      as uid app and gid app
  16    if failed port 30000 then restart
  17    if 5 restarts within 5 cycles then timeout
  18    depends on swiftiply

以上で完了。

現在、http://merbi.st/ は上記の設定で動いています。

See Aslo

追記

しばらく運用してみたのですが、プロセスが数時間に一回ぐらいのペースで落ちる問題があったので、Swiftiplyの代わりにPoundを使う構成に変えました。 Swiftiplyは次のバージョン0.7.0から、クラスタリングのサポートが強化されるようなので、それまで待ってみた方が良いかもしれないですね。

posted by Png genki on Fri 20 Feb 2009 at 16:23

Ruby-1.9.1を使うと、 以下のようにして簡単にRubyVMのInstaractionSequenceを見る事が出来ます。

   1  >> puts RubyVM::InstructionSequence.new("puts 'Hello, world!'").disasm #=> nil
   2  == disasm: <RubyVM::InstructionSequence:<compiled>@<compiled>>==========
   3  0000 trace            1                       (   1)
   4  0002 putnil           
   5  0003 putstring        "Hello, world!"
   6  0005 send             :puts, 1, nil, 8, <ic>
   7  0011 leave            

生成したInstractionSequence(aka iseq)は、evalメソッドを呼び出して実行する事もできます。

   1  >> RubyVM::InstructionSequence.new("puts 'Hello, world!'").eval #=> nil
   2  Hello, world!

さらに、to_aメソッドで個々のインストラクションに分解する事も出来ます。

   1  >> RubyVM::InstructionSequence.new("puts 'Hello, world!'").to_a
   2  ["YARVInstructionSequence/SimpleDataFormat", 1, 1, 1, {:arg_size=>0, :local_size=>1, :stack_max=>2}, "<compiled>", "<compiled>", :top, [], 0, [], [1, [:trace, 1], [:putnil], [:putstring, "Hello, world!"], [:send, :puts, 1, nil, 8, nil], [:leave]]]

posted by Png genki on Fri 20 Feb 2009 at 01:49

以前要望があった気がしたので、 PokéDia-1.2のアップデート を記念して、 MacOSXのSafariで自動的に選択した文字列をコピーするSIMBLプラグイン SafariCopyOnSelect を作ってみました。

SafariCopyOnSelect.bundle.zip

インストール方法

  1. まずはSIMBL をインストールします
  2. 上述のSafariCopyOnSelect.bundle.zipファイルをダウンロードして展開します
  3. 展開されたSafariCopyOnSelect.bundleを、 ~/Library/Application Support/SIMBL/Plugins/の下にコピーします。 ディレクトリが無い場合は作成してください。
  4. Safariのプロセスを終了し、Safariをもう一度起動します

これでOKです。 一時的にこの機能をオフにする場合は、 以下のようにメニューから「Copy On Select」をオフにしてください。

ss01

オンに戻せば再び有効化されます。

posted by Png genki on Thu 19 Feb 2009 at 18:39

ハマったので覚えるために記事にしました。

サーバ等で

   1  $ mkdir repo.git
   2  $ cd repo.git
   3  $ sudo git init --bare --shared=true

"空"の共有リポジトリができました。

ローカルマシンで

その後、remote add, add, commit, push

   1  git init
   2  git remote add origin ssh://git.s21g.com/mnt/git/repo.git 
   3  git add .
   4  git commit -m "initial import"
   5  git push origin master

サーバのrepo.gitにファイルが追加された時点でcloneできるようになります。空のリポジトリをcloneしようとしてもエラーが出ます:

   1  $ git clone ssh://git.s21g.com/mnt/git/repo.git 
   2  fatal: no matching remote head

おまけ:git URLを確認する git remote show origin

   1  git remote show origin
   2  * remote origin
   3    URL: ssh://git.s21g.com/mnt/git/repo.git

posted by Png satoko on Thu 19 Feb 2009 at 14:21

長らくお待たせしておりました、PokéDiaのバージョン1.2が、 iTunesストアからアップデート可能になりました。

ss

PokéDia-1.2 (iTunes Store)

PokéDia-1.2では、重要なバグ(稀にメモが消える、メモの表示が乱れる事がある)の修正と、一覧表示機能、検索機能の実装を行いました。日本語でお使いのiPhoneでは絵文字を使うことも出来ます。

今後とも、頂いているご要望をもとに、さらなる機能改善をおこなって参りますので、ご愛顧のほどをお願いいたします。

See Also

posted by Png genki on Thu 19 Feb 2009 at 12:43

thinを使ってmerbアプリケーションをrackupする方法のメモです。 以下のようなconfig.ruファイルを用意します。

   1  # config.ru
   2  require 'rubygems'
   3  require 'merb-core'Merb::Config.setup(
   4    :merb_root   => File.expand_path(File.dirname(__FILE__)),
   5    :environment => ENV['RACK_ENV'])
   6  Merb.environment = Merb::Config[:environment]
   7  Merb.root = Merb::Config[:merb_root]
   8  Merb::BootLoader.run
   9  
  10  use Merb::Rack::Static, Merb.dir_for(:public)
  11  run Merb::Rack::Application.new

あとは、以下のようなコマンドで起動します。

   1  % RACK_ENV=development thin -R config.ru start

posted by Png genki on Thu 19 Feb 2009 at 02:54

   1  % git pull <repo-name> <branch>
は、
   1  % git fetch <repo-name>
   2  % git merge <repo-name>/<branch>
と同じ事です。

git pull --rebaseというのもよく見かけますが、これは

   1  % git fetch <repo-name>
   2  % git rebase <repo-name>/<branch>
と同じ事です。mergeの代わりにrebaseを使います。

See Also

posted by Png genki on Thu 19 Feb 2009 at 01:18

githubなどを使っていると、簡単にリポジトリをフォーク出来るので、 有名なプロジェクトになると、数十のリポジトリが並走している事もしばしばです。 多くの場合、フォークのツリーをたどっていけば、ルートになるリポジトリが見つかるのですが、ルートになっているプロジェクトのコードが最新であるとは限りません。 フォークしたリポジトリの方にバグの修正が入っていたり、パッチがあたっていたりする事も良くあります。

そのような場合には、

   1  % git remote add <repo-name> <url>
のようにして、関心のあるremoteリポジトリを登録しておきます。 登録が済めば、
   1  % git fetch <repo-name>
でリモートのブランチを手元に持ってくる事が出来ます。 例えば手元のmasterとリモートのmasterの差異を知りたければ、

   1  % git diff master..<reponame>/master

のようにする事で調べられます。

posted by Png genki on Thu 19 Feb 2009 at 00:59

注:2009.2.23 公開されました:2.18 申請。申請用URLとして使用。


Icon.png ezPhotoMail

iPhoneで撮った写真をリサイズしてメール(Gmail)で送信できるアプリです。

iTunes(日本) URL:
http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=305784712&mt=8

個人的に、(携帯メールしか持たない)じじばばに子供の写真を簡単にリサイズして送りたいと思ったので作りました。ezPhotoMailのzは"じー(じぃじ)"を兼ねています。

ezPhotoMailUI.png

  • 宛先:入力、又はアドレス帳からの指定
  • 件:日本語(ISO-2202-JP)
  • 画像サイズ:設定で変更可(デフォルト320x240)
    ※指定サイズにフィットする形で縮小されるので、縦長サイズ(480x800など)を指定した場合は人物等が引き延ばされた感じになってしまいます。
  • Gmailでの送信になります

前回入力したToとタイトルは保存され、次回起動時に再利用できるようになっています。また、本文入力はありません。

posted by Png satoko on Wed 18 Feb 2009 at 06:37 with 5 comments

納品物の中によく「ソースコードのドキュメント」とありますが、いちいち作るのがめんどくさいです。

しかも、そのドキュメント作成の工程が「○人日」とかになってたりします。

ドキュメントは大切ですが、どうしても楽したいですよね。(僕だけ?)

そこで、Doxygenを使ってドキュメントを自動生成します。

Doxygenを使うドキュメント生成は、

  • 普段から決まったコメントの付け方をする
  • Doxygenの使い方を覚える
  • Doxygenでドキュメントを生成している時間待つ

の3つを行うだけで、簡単にできます。

生成されるドキュメントには、HTML形式や、TeX形式などがあります。

準備編

インストール

とりあえず、Linuxのみのインストール方法です。

yum系の場合(CentOS5.2 で確認)

   1  # yum install doxygen

apt系の場合(確認してないですが、おそらく)

   1  # apt-get install doxygen

ソースコードのコメントの書き方

JavaDocスタイルとQtスタイルに対応しています。

詳しくは、Doxygenのマニュアルのコードのドキュメント付けを参照してください。

普段からこの書き方を心がけていれば、初めは面倒でも、だんだんと慣れてくると思います。

Doxygenを使ってみる

準備が終わったところで、さっそくDoxygenを使っていきます。

Doxyfileの生成

まず、プロジェクトのディレクトリに移り、

   1  $ doxygen -g
とし、Doxyfileというものを生成します。

Doxyfileの編集

次に、生成されたDoxyfileを編集します。

デフォルトでは、Doxyfileと同じディレクトリのソースコード類に関してドキュメントが生成されます。

これは、460行目あたりの INPUT のあたりを変更すると、別のディレクトリを参照するように変更できます。

必ずしておくほうが良いのは、230行目あたりの

   1  EXTRACT_ALL            = NO
   2  EXTRACT_PRIVATE        = NO
   3  EXTRACT_STATIC         = NO
   4  EXTRACT_LOCAL_CLASSES  = YES
   5  EXTRACT_LOCAL_METHODS  = NO

を、

   1  EXTRACT_ALL            = YES
   2  EXTRACT_PRIVATE        = YES
   3  EXTRACT_STATIC         = NO
   4  EXTRACT_LOCAL_CLASSES  = YES
   5  EXTRACT_LOCAL_METHODS  = NO

に変更することです。

今回は、超簡単な使い方なので、詳細は省きます。

ドキュメントの生成

   1  $ doxygen
と実行すると、ドキュメントの生成が始まります。

しばらく待つと、完成です。

最後に

以上で超簡単なDoxygenの使い方でした。

これで、「ソースコードのドキュメント1人日で作ってね」と言われても、「え、そんなの10秒でできますが」 と答えれますね!

作業効率がUPです♪

また時間があれば、Doxygenの使い方を詳しく見ていきたいと思います。

posted by Png y_tsuda on Tue 17 Feb 2009 at 02:11