'Rask' - Terminatable Task Engine
Ruby JavaScript
Switch branches/tags
Nothing to show
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
doc
generators/rask
lib
samples
script
spec
.gitignore
Gemfile
Gemfile.lock
History.txt
Manifest.txt
PostInstall.txt
README.rdoc
Rakefile
install.rb

README.rdoc

rask

English Document

DESCRIPTION:

Rask を使うと、タスク処理をシンプルに記述できます。

タスクの実行状態が自動的に永続化されるので、
タスクの中断、復帰が容易です。
これらの処理は、web のように処理がまばらな環境での利用を想定しています。
どうしてもサーバを再起動しなければいけない時など、バックエンドタスクの中断、復帰を安全に実装できます。
また、膨大な時間がかかる計算処理などでの利用も考えられます。

FEATURES/PROBLEMS:

  • 「途中で止めても復帰できるタスクエンジン」

  • シンプルなステートマシンの記述 (Act As State Machine と似てる)と状態の永続化

  • デーモン起動によるブロッキング回避

    • たとえば、webなんかだとタイムアウト回避処理が容易に記述できる

    • webビデオエンコーダとか、サイトの大量メール配信とか

    • デーモンが落ちても永続化されているので処理の途中から復帰可能

      • kill で落とした場合は安全に状態を維持したまま終了できる

  • 永続化はMarshal使っているだけなので drb 組み合わせて、強力な web のバックエンド構築ができる気がするが試していない

  • 内部動作はワーカースレッドで処理しており、スレッド数も変更できるので、処理に応じたチューンが可能

    • CPUパワーやメモリ量から逆算して、並列化の度合いを調整することでアホみたいにサーバが重たい状況も回避できる。

  • タスクのグルーピング

    • ユーザー毎にタスクを分けて管理したりとか、ブラウザゲーム用途でも使える。

INSTALL:

gem install rask

INSTALL for Ruby On Rails Plugin:

Rails のプラグインとしてインストールすると、 バックグラウンドタスクジェネレータが利用できるようになります。

script/plugin install git://github.com/mewlist/Rask.git
  • タスクジェネレータ (generator)

    • タスクは、lib/rask 以下に雛形が生成されます

script/generate rask test
     create  lib/rask/
     create  script/rask/
     create  lib/rask/test_task.rb
     create  script/rask/test_task.rb
  • タスク起動スクリプト

script/runner script/rask/test_task.rb start   # デーモンの起動
script/runner script/rask/test_task.rb restart # 再起動
script/runner script/rask/test_task.rb stop    # 停止

Rails のフレームワークとコードを共通化したタスクの管理が行えるようになるので、 ActiveRecord の構文が組み込めます。

注意点としては、タスク内で使用しているモデルのコードが変更された場合は、 デーモンで読み込まれている実行コードとの不整合が生じるので、タスクを再起動してください。

SYNOPSIS:

  • サンプルコード (samples/test.rb)

require 'rubygems'
require 'rask'

# 数値のカウントアップ 10 までカウントするタスク
class CountupTask < Rask::Task
  # define_state でステートマシンを作ることができます
  define_state :start,   :initial => true       # 初期状態
  define_state :running                         # 実行
  define_state :finish,  :from    => [:running] # 終了 (遷移元は:runningからのみ)

  def start # 定義と同名の関数を定義することで自動的にコールバックされます
    @count = 0
    p "start"
    transition_to_running # :running へ遷移
  end

  def running
    p "running count => #{@count+=1}"
    transition_to_finish if @count>=10 # :finish へ遷移
  end

  def finish
    p "finished"
    destroy # タスクの破棄をする
  end
end

Rask.insert CountupTask.new # タスクの登録

Rask.daemon # デーモンとして実行

タスク定義と、デーモンの実行コードがそろったら以下のようにデーモンを起動

$ ruby samples/test.rb

test.rb を実行するたびにタスクが新しく登録され実行する様子がわかる Raskはデーモンの二重起動を抑制するので複数のプロセスが立ち上がることはない

デーモンが起動すると、プロセスIDファイルが rask の作業ディレクトリに自動的に生成されるので デーモンの終了は以下のようにできる

$ kill `cat /tmp/rask/test.rb.pid`

kill -TERM されたプロセスは、そのタスクのステートマシンの状態を壊さない。 いつでも、test.rb を再実行することで前回中断したところから続きのタスクを実行することができる。 シビアな運用環境で役立つはず。

タスクの分類

タスクにグループ名を指定しておくことで、特定のグループ名を持つタスクだけを取得したり、処理することができます。 「特定のユーザーが起動したタスクのみを監視したい」といったことが可能です。

Rask.insert CountupTask.new('user_id') # user_id という名前のグループを登録

デーモン起動時に特定のグループIDを持つタスクのみ処理することができます。

Rask.daemon(:group=>'user_id') # user_id という名前のグループに属するタスクのみを処理

このタスクを監視したい場合は、以下のようにタスクのリストを取得します。

Rask.task_ids(:group=>'user_id').each { |task_id|
  task = Rask.read(task_id) # 読み取り専用でタスクを開く
  p "TaskState >>>>> #{task.state} \n"
}

チューニング

  • ワーカースレッドの数を調整

スレッドを増やすと、ワーカーが次々とタスクを処理してくれるので、タスク開始までの待ち時間が緩和されます。

Rask.thread_max_count = 100
Rask.daemon
  • メインスレッドのポーリング間隔の調整

デーモン起動時のオプションでポーリングの間隔を調整できます。

Rask.daemon(:sleep=>0.5)

REQUIREMENTS:

ruby1.8.7で作ってる

Changelog

  • v0.0.6

    • read が落ちるバグの修正

    • タスク内で発生した例外コールバックの追加

    • Task::on_exception will be called when some exception raised in Task Processing.

  • v0.0.5

    • rails にて複数タスク実行可能に修正

    • 例外をキャッチするようにした

      • 落ちた場合はデフォルトで BASE_DIR/suspended/ フォルダにタスクファイルを移動するのでコード修正後戻せば復帰可能

    • If exception raised, Rask delete the task and keep the task file to “BASE_DIR/suspended” directory.

    • Rails generator is fixed.

  • v0.0.4

    • Integration for Ruby On Rails

      • rails のジェネレータ化、プラグイン化コードの統合

  • v0.0.3

    • read メソッドで取得したインスタンスの実行制限処理

    • 英語ドキュメントの追加(/doc)

  • v0.0.2

    • グループ化、安全なプロセス中断処理追加

  • v0.0.1

    • 方向性をはっきりさせた

  • v0.0.0

    • 作ってみた

LICENSE:

(The MIT License)

Copyright (c) 2010 mewlist / Hidenori Doi

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.