フォーチュンサモナーズ
最新 追記

Don'tStopMusic

2003|07|08|09|10|11|12|
2004|01|02|03|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|12|
2006|01|02|03|04|05|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|

カテゴリ別 2003年 | 2004年 | 2005年 | 2006年 | 2007年 | 2008年

知り合いサイト: よんだもの / 暴想 / Linuxでやる夫 / 新宿Vipper / 僕だけが幸せになればいいのに。


2007-09-01 この日を編集

_ [Ruby] 暴想: Rubyでexitの挙動をテストする方法 このエントリーを含むブックマーク

例外のテストには assert_raise を使います。

test_die.rb

require 'test/unit'
 
def die
  exit(1)
end
 
class TC_die < Test::Unit::TestCase
  def test_die
    assert_raise(SystemExit) do
      die
    end
  end
end

実行

$ ruby -v test_die.rb
ruby 1.8.6 (2007-06-07 patchlevel 36) [i686-linux]
Loaded suite test_die
Started
.
Finished in 0.001641 seconds.
 
1 tests, 1 assertions, 0 failures, 0 errors

そういえば、メソッド内で exit するという発想はなかったですね。 私はといえば、クラスのメソッドの中では定義した例外を上げて、そのクラスを使っているコマンドの方で例外を捕捉して改めて exit させてます。普通どうしてるんでしょうかね。↓例

class FooError < StandardError; end
class Foo
  def bar
    raise FooError
  end
end
 
begin
  foo = Foo.new
  foo.bar
  ...
rescue FooError
  exit(false)
end

2007-09-04 この日を編集

_ [Ruby] m17n 質問ページ このエントリーを含むブックマーク

RWiki 上に ruby-m17n に関する質問ページ m17nQuestions ができました。

疑問などを書いておくとまつもとさんが回答してくれるかもしれません。

_ [Ruby] IronRuby が RubyForge に このエントリーを含むブックマーク

I'm happy to announce that we're live on Rubyforge today!

IronRuby on Rubyforge!

Ruby の .NET な処理系である IronRuby が RubyForge でホスティングされるようになりました。まあ、RubyForge に来たから何が変わるわけでもありませんが、Ruby コミュニティと近いところにいるという意思表示でしょう。

アルファリリースの時と比べて Enumerable などが多少実装されていますが、まだまだ完成度は低いです。実装言語は C# ですので、Ruby に詳しくて C# も書け、Windows 環境で Ruby を積極的に広めていきたいという方参加してみてはいかがでしょうか。


2007-09-10 この日を編集

_ [Ruby] Ruby 技術者認定試験の問題を予想してみました このエントリーを含むブックマーク

さらに追記:第二回試験を受けましたが、この日記の予想問題とはあんまり近くはありませんでした。試験勉強をされる方は、リファレンスマニュアルと NaCl さん謹製のRuby認定試験対策問題を読むのが良いと思います。

追記:まつもとさん曰く実際の問題はもう少しストレートで優しいものになる予定とのことです。

10 月に実施される予定の Ruby 技術者認定試験の問題を予想してみました。とりあえず 30 問。組み込み関数・変数・定数・クラスの問題がほとんどないので、増やすつもりです。

エントリーレベルだそうなので簡単な問題にしてみましたが、簡単すぎでしょうかね。(会社の後輩に見せたところエントリーレベルにしては難しいとの評でした。SJC-P を念頭においていたのでひねった問題にしてしまったかもしれません……)除いた分野は、ブロック、スレッド、正規表現、メタプログラミング、オブジェクト指向プログラミングです。また、処理系は CRuby 1.8.6-p36 前提です。

問題の分野の分け方や出題形式は SJC-P(Sun Certified Programmer for the Java 2 Platform)を真似しました。

念為免責文。なお、私は Ruby アソシエーションとは無関係な一個人ですので、以下の予想問題は予想問題に過ぎません。実際の試験に出る範囲や出題形式はまるで異なるかもしれません。また、この予想問題が解けたからといって実際の Ruby 技術者認定試験が解けるとは限りません。

では、以下予想問題です。

宣言、初期化、スコープ

Q.1 「http://example.org/」と出力される以下のプログラムの(A)にふさわしいものはどれか
class MySite
  def (A)
    @url = url
  end
  def url
    @url
  end
end
 
site = MySite.new("http://example.org/")
puts site.url
  1. MySite(url)
  2. new(url)
  3. initialize(url)
  4. constructor(url)
Q.2 「a」と出力される以下のプログラムの(A)にふさわしいものはどれか
class Exam
  def self.foo
    puts "a"
  end
  def foo
    puts "b"
  end
end
 
(A)
  1. exam = Exam.new
    exam.foo
  2. Exam.foo
  3. include Exam
    foo
  4. extend Exam
    foo
Q.3 以下のプログラムの実行結果はどれか
class Hello
  puts "hello, world"
end
  1. SyntaxError で終了
  2. NameError 例外で終了
  3. 「hello, world」と出力
  4. 何も表示されない
Q.4 Child は Parent のサブクラスである。以下のプログラムの(A)にふさわしいものはどれか
class Parent
end
 
class (A)
end
  1. Child :: Parent
  2. Child extends Parent
  3. Child < Parent
  4. Child inherit Parent
Q.5 以下のプログラムの実行結果はどれか
class Apple
  def color
    "red"
  end
  private :color
end
 
class GreenApple < Apple
  def color
    "green"
  end
end
 
apple = GreenApple.new
puts apple.color
  1. SyntaxError で終了
  2. NoMethodError 例外で終了
  3. 「green」と出力
  4. 「red」と出力
Q.6 以下のプログラムの実行結果はどれか
module A
  def hello
    puts "hello, A"
  end
end
 
class B
  def hello
    puts "hello, B"
  end
end
 
class C < B
  include A
end
 
obj = C.new
obj.hello
  1. 「hello, A」「hello, B」と出力
  2. 「hello, A」と出力
  3. 「hello, B」と出力
  4. 何も表示されない
Q.7 以下のプログラムの実行結果はどれか
class Parent
  def test(text)
    puts text
  end
end
 
class Child < Parent
  def test(text, number)
    super
    puts number
  end
end
 
obj = Child.new
obj.test("hello", 10)
  1. 「hello」「10」と出力
  2. 「10」と出力
  3. ArgumentError 例外で終了
  4. 何も表示されない
Q.8 以下のプログラムの実行結果はどれか
$text = "hello"
class Test
  def initialize
    @text = "good bye"
  end
 
  def say_hello
    puts text
  end
end
 
obj = Test.new
obj.say_hello
  1. 「hello」と出力
  2. 「good bye」と出力
  3. NameError 例外で終了
  4. ArgumentError 例外で終了
Q.9「-10」と出力される以下のプログラムの(A)はどれか
class MyInteger
  def initialize(i)
    @i = i
  end
  def (A)
    - @i
  end
end
 
i = MyInteger.new(10)
puts -i
  1. -
  2. -@
  3. -$
  4. <UnaryMinus>

リテラル

Q.10 整数リテラルとして誤っているものはどれか
  1. 1_000
  2. 0d1000
  3. 1,000
  4. 1000
Q.11 "STRING" と等価のリテラルはどれか
  1. %r!STRING!
  2. %w!STRING!
  3. %!STRING!
  4. %s!STRING!
Q.12 {1=>2, 3=>4} と等価のリテラルはどれか
  1. {1, 2, 3, 4}
  2. %h{1 2 3 4}
  3. [1, 2, 3, 4]
  4. "{1=>2, 3=>4}"
Q.13 37 と等価なリテラルはどれか
  1. 0x25
  2. ?&
  3. 0b0101010
  4. 044

フロー制御

if/unless/case-when

Q.14 以下のプログラムの実行結果はどれか
i = 0
if i
  puts "true"
else
  puts "false"
end
  1. SyntaxError で終了
  2. 「true」と出力
  3. 「false」と出力
  4. 何も表示されない
Q.15 以下のプログラムの実行結果はどれか
puts "foo" unless true and false || false or true
  1. SyntaxError で終了
  2. 「foo」と出力
  3. UnreachedStatementError で終了
  4. 何も表示されない
Q.16 以下のプログラムの実行結果はどれか
case 123
when /^\d$/
  puts "digit"
when Integer
  puts "integer"
when Fixnum
  puts "fixnum"
else
  puts "other"
end
  1. 「digit」と出力
  2. 「integer」と出力
  3. 「fixnum」と出力
  4. 「other」と出力

for/while/until/each

Q.17 「1234」と出力される以下のプログラムの(A)はどれか
(A)
  print i
end
  1. for i in 1..4
  2. for i in 1...4
  3. for (i = 0; i < 4; i++)
  4. for (i = 0; i < 4; i++); do
Q.18 以下のプログラムの実行結果はどれか
i = 10
while i
  i = i - 1
  print i
end
  1. 「10987654321」と出力
  2. 「987654321」と出力
  3. SyntaxError で終了
  4. 実行が停止しない
Q.19 「12345」と出力される以下のプログラムの(A)(B)はどれか
[1, 2, 3, 4, 5].each (A)
  print i
(B)
  1. (A) { (B) }
  2. (A) begin |i| (B) end
  3. (A) do |i| (B) end
  4. (A) (|i| (B) )

break / retry / redo

Q.20「1234」と出力される以下のプログラムの(A)はどれか
for i in [1, 2, 3, 4, 5]
  print i
  if i > 3
    (A)
  end
end
  1. return
  2. break
  3. retry
  4. redo

begin-rescue-ensure

Q.21 以下のプログラムの実行結果はどれか
begin
  array = [1, 2, 3, 4, 5]
  num = array.fetch(6)
  puts num
rescue ArgumentError
  puts "ArgumentError"
rescue IndexError
  puts "IndexError"
rescue StandardError
  puts "StandardError"
end
  1. 何も出力しない
  2. 「ArgumentError」と出力
  3. 「IndexError」と出力
  4. 「StandardError」と出力
Q.22 以下のプログラムの実行結果はどれか
begin
  raise StandardError
rescue StandardError
  exit
ensure
  puts "ensure"
end
  1. 「ensure」と出力
  2. 何も出力しない
  3. SystemExit 例外で終了
  4. 「ensure」と出力して SystemExit 例外で終了

例外

Q.23 ライブラリ hello が存在しない場合、以下のプログラムの実行結果はどれか
begin
  require "hello"
rescue
  puts "hello not found"
ensure
  puts "bye"
end
  1. 何も出力しない
  2. 「hello not found」と出力
  3. 「bye」と出力
  4. 「bye」と出力して LoadError 例外で終了

組み込みライブラリ

Q.24 Integer クラスの説明として正しいものはどれか
  1. 32bit整数クラス
  2. 整数の抽象クラス
  3. 多倍長整数クラス
  4. 実数の抽象クラス
Q.25 TrueClass クラスの説明として正しいものはどれか
  1. true は TrueClass の唯一のインスタンスである
  2. Boolean クラスのサブクラスである
  3. Comparable モジュールをインクルードしている
  4. TrueClass.new でインスタンスを生成できる

標準ライブラリ

Q.26 drb ライブラリの説明として正しいものはどれか
  1. デバッガライブラリ
  2. 分散オブジェクトシステムライブラリ
  3. メール送信ライブラリ
  4. ファイル操作ユーティリティ
Q.27 コマンドラインオプションの解析のためのライブラリはどれか
  1. getoptlong
  2. generator
  3. strscan
  4. pp

基礎

Q.28 以下のプログラムの実行結果はどれか
hello = "hello, world."
hello.chop
puts hello
  1. SyntaxError で終了
  2. 何も出力しない
  3. 「hello, world.」と出力
  4. 「hello, world」と出力
Q.29 以下のプログラムの実行結果はどれか
def mul10(i)
  i = i * 10
end
 
n = 10
mul10(n)
puts n
  1. 「10」と出力
  2. 「100」と出力
  3. 「10101010101010101010」と出力
  4. SyntaxError で終了
Q.30 以下のプログラムの実行結果はどれか
i = 1 / 3
puts i
  1. 「0.3」と出力
  2. 「1/3」と出力
  3. 「0」と出力
  4. 「0.33333...」と出力

_ [Ruby] Ruby 技術者認定試験予想問題 解答編 このエントリーを含むブックマーク

style="color: white" してます。選択するなりテキストエリアにコピーするなりして読んでください。

Q.1
3. initialize(url)
Q.2
2. Exam.foo
Q.3
3. 「hello, world」と出力
Q.4
3. Child < Parent
Q.5
3. 「green」と出力
Q.6
2. 「hello, A」と出力
Q.7
3. ArgumentError 例外で終了
Q.8
3. NameError 例外で終了
Q.9
2. -@
Q.10
3. 1,000
Q.11
3. %!STRING!
Q.12
1. {1, 2, 3, 4}
Q.13
1. 0x25
Q.14
2. 「true」と出力
Q.15
4. 何も表示されない
Q.16
2. 「integer」と出力
Q.17
1. for i in 1..4
Q.18
4. 実行が停止しない
Q.19
3. (A) do |i| (B) end
Q.20
2. break
Q.21
3. 「IndexError」と出力
Q.22
1. 「ensure」と出力
Q.23
4. 「bye」と出力して LoadError 例外で終了
Q.24
2. 整数の抽象クラス
Q.25
1. true は TrueClass の唯一のインスタンスである
Q.26
2. 分散オブジェクトシステムライブラリ
Q.27
1. getoptlong
Q.28
3. 「hello, world.」と出力
Q.29
1. 「10」と出力
Q.30
3. 「0」と出力
本日のツッコミ(全3件) [ツッコミを入れる]

_ kentaro [解答編の、A7とA11の番号と内容が、問題の選択肢のそれと食い違ってる気がします。]

_ だて [あ、確かに。ありがとうございます。修正しました。]

_ うう〜〜〜ん [19/30でした・・・。もっと勉強しないと。。]


2007-09-13 この日を編集

_ [Ruby] 予約語と同じ名前のメソッド このエントリーを含むブックマーク

def
def foo
  # ...
end

上記スクリプトは SyntaxError にならない(def がふたつあるのに注意)。

今日の Ruby 落とし穴 - METAREAL

上記のコードは、

def def(foo)
  # ...
end

と解釈されます。つまり 'def' という名前のメソッド定義をしています。Ruby では def や class といった予約語と同じ名前のメソッドが定義できたりします。呼び出すには send を使わないといけませんけれども。実行してみましょう。

$ ruby -v -e'
def
def foo
  puts 1
end
send(:def, nil)
'
ruby 1.8.6 (2007-06-07 patchlevel 36) [i686-linux]
1
 
$ ruby -v -e'
def if
  puts 1
end
send(:if)
'
ruby 1.8.6 (2007-06-07 patchlevel 36) [i686-linux]
1

予約語と同じ名前のメソッドが定義できるのはいいですけど、def とメソッド名の間に改行を許しているのは理由があるのでしょうかね。def や class のように後に字句が続く場合には空白の代わりに改行でも OK というルールなのかな。

$ ruby -v -e '
class
Foo
end
p Foo.new
'
ruby 1.8.6 (2007-06-07 patchlevel 36) [i686-linux]
#<Foo:0xb7d12740>
 
$ ruby -v -e '
class Foo
alias
tos
to_s
end
p Foo.new.tos
'
ruby 1.8.6 (2007-06-07 patchlevel 36) [i686-linux]
"#<Foo:0xb7d126b4>"

どうやらそうっぽいですね。

追記

ささださんに、レシーバがあれば send 使わなくてもいいと教えてもらいました。実験。

$ ruby -v -e '
class Foo
  def def
    puts 1
  end
end
Foo.new.def
'
ruby 1.8.6 (2007-06-07 patchlevel 36) [i686-linux]
1

ということは、DSL で def やら if が使えるということかな。

本日のツッコミ(全2件) [ツッコミを入れる]

_ ささだ [レシーバがあれば,send使わなくてもよべますよ.]

_ だて [なるほど。レシーバがあれば区別できるから普通に呼べますね。追記しました。 ささださんのところで作っている「Ruby ..]


2007-09-16 この日を編集

_ [Ruby] 速くなると敷居が高くなる? このエントリーを含むブックマーク

やってしまったのか? Ruby1.9。
高機能になるのは、まったく構わないのですが、
敷居を高くしては下も子もありません。

固定長整数演算がどれだけ早くなったとしても、そういう使い方をするユーザーがどれだけいるのやら。
今発行されている書籍では、主にCGIやデータベースでの使い方ばかりのはずです。
噂されていた通り、Rubyは1.8で死んでしまったのだろうか?
1.9は救世主となるのか?

ぺんブロ | 初心者離れが決定したRuby1.9

敷居が高くなる理由が書かれてないので、良くわかりません……

YARV は MatzRuby(Ruby 1.8 まで) の仕様を引き継ぎつつ VM 化することで実行速度を改善しようというものです。YARV と MatzRuby で(仕様が明確でないため)、あるいは 1.8 と 1.9 で(m17n など)非互換な部分はあります。ですが、違う言語にするわけではありませんので、「CGI やデータベースでの使い方」は YARV ベースの 1.9 でもできます。

非互換な部分によって 1.8 のアプリやライブラリが全滅して 1.9 のユーザが増えないということなら敷居が高いでしょう。前に YARV を使って gem インストールできるプログラムをひたすら実行確認した限りでは、動かなくなったとしても、そう多くない労力で 1.9 対応できそうでした。それに 1.9 がほんとうに全然使われないなら、より互換性を重視したものにするんじゃないかと。


2007-09-20 この日を編集

_ [Ruby] Ruby における地域格差 このエントリーを含むブックマーク

Rubyアソシエーションは9月19日、Rubyの資格認定試験の第1回を10月27日に島根県松江市で実施すると発表した。Rubyアソシエーションからの委託を受けて、伊藤忠テクノソリューションズ(CTC)が認定事業を担当する。試験は90分のペーパーテストで、選択式の問題50問を出題する。受験費用は1万5750円。第2回試験は12月1日に、第3回試験は2008年1月19日に東京と松江の2会場で行う予定。

Ruby検定の詳細を発表、Rubyアソシエーション − @IT

Rubyの資格認定試験の第1回を10月27日に島根県松江市で実施……島根県松江市……松江……

東京駅(東京) から 松江駅(島根) → 30,480円 3回乗換。受験費用よりも旅費の方がはるかに高いです。第三回まで待ちますか……

試験の詳細について公式ページがありますが、9/20 0 時現在 申し込みページは 403 でした。それと試験の出題範囲は発表する予定がないのでしょうかね。

9/20 朝追記

昨晩 403 だった Ruby認定試験のご案内と申し込みページに出題範囲が記載されていました。実行環境も出題範囲なのですね。なるほど。また、第一回の申し込みは昨日の昼の時点で定員オーバーだったようです。


2007-09-21 この日を編集

_ [Rails] Rails のセキュリティガイド このエントリーを含むブックマーク

QuarkRuby: Ruby on Rails Security Guide では、Rails でアプリを開発する際にセキュリティ面で気を付けなければいけないことを簡潔にまとめています。

いま社内向けに Rails のセキュリティガイドラインをまとめているので参考になります。上記のページに、OS コマンドインジェクションとセッション固定化、HTTP ヘッダインジェクションを追加すれば一般的な脆弱性は大体カバーできますね。

なお、Rails のセキュリティについて興味のある方は、前田さんのWebアプリケーションセキュリティフォーラム発表資料は必読です。

追記

自分の備忘録として脆弱性に関してまとまった情報があるサイトや資料を挙げておきます。

_ [Ruby] RubyGems が Ruby 1.9 でテストが通ったようです このエントリーを含むブックマーク

455 tests, 1600 assertions, 0 failures, 0 errors

Wooo!

RubyGems Tests Pass on 1.9

すばらしい。

ENV['FOO'] = nil を ENV.delete 'FOO' に変更したなどの 1.9 対応にあたっての修正点を挙げています。こういう情報が集積されると便利かも。


2007-09-22 この日を編集

_ [Ruby] RubyForge の成長 このエントリーを含むブックマーク

It’s often been said that Perl’s greatest strength is CPAN, Perl’s vast collection of free libraries contributed by developers from around the world. Recently I started to wonder about RubyForge and how RubyForge stacks up against CPAN in general.

RubyForge vs CPAN - O'Reilly Ruby

ということで、RubyForge と CPAN の比較をしています。データをいくつか引用してみます。

サービス期間

CPAN
1995 年 10 月から約 10 年
RubyForge
2003 年 7 月から約 4 年

ユーザ数

CPAN
6,150 (Authorsページをスクレイピングした結果)
RubyForge
20,300

といっても、RubyForge は何もコードをリリースしていなくてもユーザ登録だけはできるので数は膨らみがちです。そこを補正すると以下のようになります。

何らかのライブラリ(CPAN)やプロジェクト(RubyForge)に関連するユーザ数
CPAN
3,774
RubyForge
3,635

プログラム数

CPAN
約 13,500
RubyForge
約 5,000

単純な数の比較では 1/3 くらいの規模に達しているようです。

元記事では続けて、CPAN は Acme 多いよねとか、 OOP 関連や Array Hash など Ruby には元から備わっているものも割とあるよねとか、差を縮めようと努力しています(笑

最後にリリース頻度を比較しています。

最近一月間でのリリース頻度

CPAN
1,133 回
RubyForge
612 回

プログラムの数の開きの 3:1 に比べてこちらは 2:1。まだ CPAN の半分くらいですが、RubyForge も勢いは付いてきているようです。

個人的な感覚では、ウェブの分野に関しては RubyForge にほしいライブラリがないことは少なくなってきました。ただ、例えばウェブサービスの API が新しく公開されたとして、CPAN にはほんとにすぐにライブラリが上がることが多いですが、RubyForge の方はそこまでのスピードはないですね。


2007-09-28 この日を編集

_ [ソフトウェア] DB分散の次は非同期処理がウェブアプリのスケーリングのトレンドになる このエントリーを含むブックマーク

サイボウズも memcached + MySQL DB 分散

Cybozu Developer Network: MySQL Users Conference Japan 2007 講演概要 を読んで、memcached でキャッシュ& 複数の MySQL をアプリのロジックで分散化というのは、もうすっかりスケーラブルなウェブアプリの作り方として常套手段になったと思いました。

2004 年 4 月の MySQL カンファレンスでの Brad Fitzpatrick の発表 Inside LiveJournal's Backend (PDF)から約 3 年半。Mixi やはてなのようなエッジな企業はだいぶ前からこの構成を採用してますが、対法人のビジネスをしているサイボウズでも採用されたというのは一つの節目じゃないかと感じました。

その次

で、タイトルに戻りますが、memcached やデータベース分散化の次には非同期処理がトレンドになると思います。非同期処理といっても Ajax のようなクライアント側ではなくて、サーバ側です。

また Brad Fitzpatrick の発表ですが、YAPC::Asia 2007 LiveJournal: Behind The Scenes Scaling Storytime (PDF) をぜひ読んでみてください。Inside LiveJournal's Backend 以降の LiveJournal のスケーリングの経緯が分かります。

Inside LiveJournal's Backend から増えた構成要素には MogileFSPerlbalgearmanTheSchwartz があります。それぞれ注目すべきソフトウェアですが、今回は gearman と TheSchwartz に言及したいと思います。

ウェブアプリは同期処理

プレゼン資料中では、gearman は「待ち時間の少ないリモートファンクションコール“ルータ”」、TheSchwartz は「非同期ジョブ管理システム」と説明されています。これだけでは分かるような分からないような説明ですが、それぞれどのようにウェブアプリで利用すると嬉しいのでしょうか。

「非同期処理ができるから」がその答えですが、その前にウェブアプリが同期処理ということを説明します。サーバは、ユーザのリクエストに対してレスポンスを返すまで何らかの一連の処理を実施しますが、この処理はほとんどの場合シーケンシャルです。

例を挙げて説明します。例えばブログでトラックバックを受信する処理を想像してください。典型的には、

  • パラメタを解析
  • スパムかどうかチェック、スパムだったら終了
  • データベースにトラックバックを追加
  • ページを静的に生成するシステムの場合は HTML 生成
  • ブログの持ち主にメール通知

のような流れになると思います。この一連の処理がすべて終わったら、トラックバックの送信元に対して成功/失敗を返すわけです。

処理の非同期化

ところで、これらの処理はすべてシーケンシャルに実施する必要があるでしょうか。言い換えれば、トラックバック送信元に対してレスポンスを返すにあたり、すべての処理が必須でしょうか。

そう考えると、「データベースにトラックバックを追加」が成功した時点で、トラックバック送信元にレスポンスを返せることがわかります。HTML 生成やメール通知が終わるまで待たせる理由は「アプリの作りがそうなっているから」以外にありません。

こうした場合で、HTML 生成やメール通知がボトルネックになっている時に、gearman が活用できます。HTML 生成やメール通知を「リモートファンクション」として実行することで、ウェブアプリのアクションの中でシーケンシャルに処理させず、非同期にできます。別プロセスで実行するといえば想像しやすいでしょうか。非同期になると HTML 生成やメール通知の処理を待たなくて済むので、そこがボトルネックだった場合にはレスポンスが改善されます。

ジョブ管理システムで負荷を平準化

さて、トラックバック処理の一部を非同期にしましたがまだレスポンスが悪い、例えば大量のスパムのためにトラックバック処理がアプリケーション全体の負荷の多くを占めているとします。こうした時、トラックバック処理全体を「リモートファンクション」として非同期にすることで性能を改善できる可能性があります。

スパムが高負荷の原因になるのは短時間に集中してやってくるからです。ウェブアプリはリクエストがあったら即時に処理しますので、処理の一部分を非同期にしてもリクエストが溢れる恐れはなくなりません。

要約すると、「短時間に集中・即時に処理 → 高負荷」です。短時間に集中させず即時に処理しなければ高負荷に繋がらないことになります。ただし、クライアントにレスポンスを即時に返さなくてはならないことは変わりませんので、この例では必ずトラックバックは成功したことにするといった仕様上の割り切りが必要です。

「即時に処理」についてはトラックバック処理全体を「リモートファンクション」として非同期にすることで対応できそうです。では「短時間に集中」はどうやって対処すればよいでしょうか。ここで The Schwartz です。

The Schwartz はジョブの実行制御ができます。与えられたジョブを即時に実行せずに、少し待ってから実行することなどが可能です。これにより負荷の平準化を図れます。

まとめますと、ウェブアプリは gearman にトラックバック処理を依頼、gearman は The Schwartz にジョブ登録、The Schwartz はトラックバック処理を高負荷にならないようゆっくり実行、という図式です。

Ruby/Rails ユーザの場合

gearman と The Schwartz は Perl で書かれていますが、gearman の方は Ruby のクライアントがあります。

また、Ruby には非同期処理を実現するためのライブラリとして AP4R があります。gearman が投げっぱなしなのに対して、AP4R はより信頼性の高いアーキテクチャになっています。AP4R については、AP4R,Rubyで非同期メッセージングという開発者による連載記事があります。その中で Rails で AP4R を使うチュートリアルがあります。結構簡単に使えますのでぜひ試してみてください。

ジョブ管理システムには BackgrounDRb があります。また、Rails Conf Europe 2007 で Twitter の開発者 Britt Selvitelle のセッション Really Scaling Rails がありました。この発表の資料 A Small Talk on Getting Big で、Twitter で使用していると思われる独自の分散キューシステム Starling のことを触れています。オープンソースではありませんが、いずれそうするかもと匂わせてますので期待されます。

参考になるリンク

_ [Ruby] るびま 21 号 このエントリーを含むブックマーク

3 周年おめでとうございます。

これだけの間クオリティを保ちつつ発刊を続けられたのですから、惰性でも何でもすごいことだと思います。


2007-09-29 この日を編集

_ [サイト運営] apache が落ちてました このエントリーを含むブックマーク

夜間に多少アクセスが集中して、apache がお亡くなりになったようです。tDiary を CGI 実行しているからかな。スケーラブルだとか言ってる資格もないですねえ。

_ [適当] Lightweight Language AHP をしてみた このエントリーを含むブックマーク

Lightweight Language AHP とは

30 個の質問に答えると、四大軽量言語 (Perl 、Python 、Ruby 、PHP) の中で最もあなたの価値観に合った言語を教えてくれる AHP のつもりです。

Lightweight Language AHP

オススメの LL は Ruby (33%) > Python (32%) > Perl (18%) > PHP (17%) です!

記述性と変態性を重視したものの、最近 IDE が多いので Ruby の開発環境の評価を高めにしたらこうなりました。


最近のコメント:

  1. だて (09-16)
  2. ささだ (09-14)
  3. うう〜〜〜ん (09-12)

RSS
Creative Commons License
This work is licensed under a Creative Commons License
(note: text only. w/o web design, citations, (re)distributed softwares).