それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

druby でジョブキュー・サーバーを1分で作る。

Rubyの標準パッケージでJobQueueができます。処理を後回しにしたら早いとか、NoSQLとか、◯◯便利と言われるけど、私はdrubyを推したい。drubyRubyの標準パッケージで、すぐ使えて便利。

drubyとスレッドを使う

druby(分散Ruby)は、マルチスレッド化にも対応した、よく出来た分散オブジェクト技術。

drubyを使えば、通常のオブジェクトをネットワークに公開できる。

今回は、Queueクラスとdrubyを作ったジョブ・キューサーバーを数行で作る。

Queue.server.rb

メインとなるサーバー、たったこれだけで、キューサーバーが作れる。

#!/usr/bin/env ruby -Ku
#coding:utf-8
#サーバー
require 'thread'
require 'drb/drb'
#起動
q = Queue.new
DRb.start_service("druby://localhost:12345", q)
DRb.thread.join

Client.push.rb

キューサーバーに、ジョブを突っ込むクラス

#!/usr/bin/env ruby -Ku
#coding:utf-8

require 'thread'
require 'drb/drb'
q = DRbObject.new_with_uri("druby://localhost:12345") #サーバーに接続

#とりあえず、100ジョブ
100.times{|i|	q.push "we add #{i}" }

Client.pop.rb

サーバーからジョブを取り出して仕事をする。

#!/usr/bin/env ruby -Ku
#coding:utf-8

require 'thread'
require 'drb/drb'

q = DRbObject.new_with_uri("druby://localhost:12345")
loop{|i| puts q.pop}#←ここがポイント(後述

ジョブサーバーのできあがり

これに、daemons.rb でデーモン化すれば、簡単に作ることができる。MongoDBやその他NoSQLに飛ばすより、とっても楽だし。そもそもSQLに書き出して永続化することすら面倒なので単純な文字列の受け渡し程度なら、十分仕事をしてくれる、

ポイントはここ

loop{|i| puts q.pop}   #データが来るまで停止する

ここがポイント。q.pop はマルチスレッド化に対応しているので、popするべきQueueデータがなければ、そこで入力待ちになります。入力待ちで停止しますね。入力が来ない限り、loop{}を起動したrubyのmainスレッドはsleepしてお休み厨です。


入力側でpush しない限り停止するのでsleepを使わずに済みます。環境(CPU)に優しいループが作れます。

入力を待って仕事をするので、イベント・ドリブンにも近い感じすらある。

drubyおすすめポイント

マルチスレッド化プログラミングの開発に大活躍。通常スレッドプログラミングは大変だが、1スレッドに1プロセスを割り当てて、スレッド間データは共有URIを使うだけになる。スレッド管理がとても楽、スレッドのデバッグが楽ちんになる。


僕はdrubyがなければRubyのマルチスレッド・プログラミングを挫折していたと思います。drubyに感謝

参考

3 Hello, dRuby.
dRubyによる分散・Webプログラミング

だれも買わないので、続編が出ない・・・druby 便利ですよ。