ロード直後にこれを行うことは、現在のワークフローでは適切ではありません。 フローの数には制限があり、負荷が大きいとサイトは利用できなくなります。
デーモンがこれらのビデオファイルを処理する場合、はるかに良いでしょう。
デーモンのロジックは次のとおりです-デーモンはデータベースから未処理のオブジェクトを選択し(たとえば、状態フラグを使用して日付で並べ替え)、対応するビデオファイルを変換し、データベースのレコードを更新して、ステータスを「処理済み」(または「処理エラー」)に設定します。
独自のデーモンを作成するには、 デーモンライブラリを使用できます(奇妙なことに)。 デーモンは、2つの部分で構成されます。バックグラウンドプロセスを制御するスクリプトと、デーモンロジックを含むスクリプトです。 私たちの場合、これらはscript / video_converter_controlおよびlib / video_converterファイルになります。
スクリプト/ video_converter_control:
require 'rubygems'
require 'daemons'
options = {:app_name => "video_converter",
:ARGV => ARGV,
:dir_mode => :script,
:dir => '../tmp/pids',
:log_output => false,
:multiple => false,
:ontop => false,
:mode => :load,
:backtrace => false,
:monitor => false
# daemons ( monitor), monit
}
Daemons.run(File.join(File.dirname(__FILE__), '../lib/video_converter.rb'), options)
lib / video_converter:
require File.dirname(__FILE__) + '/../config/boot'
require RAILS_ROOT + "/config/environment"
SLEEP_TIME = 1
logger = RAILS_DEFAULT_LOGGER
loop do
video = Video.find(:first, :conditions => {:state => Video::PENDING_STATE}, :order => "id ASC")
success = video.process
if success.empty?
video.update_attribute(:state, Video::CONVERTED_STATE)
else
logger.info "VideoConverter: video #{video.id} converting failure"
video.update_attribute(:state, Video::FAILURE_STATE)
end
sleep(SLEEP_TIME)
end
次のようにデーモンを操作できます。
estarter@ny $ ./script/video_converter_control status
video_converter: no instances running
estarter@ny $ ./script/video_converter_control start
estarter@ny $ ./script/video_converter_control status
video_converter: running [pid 5957]
estarter@ny $ ./script/video_converter_control stop
estarter@ny $ ./script/video_converter_control status
video_converter: no instances running
ここで、コンバータの「電力」を増やします。 複数のビデオファイルを同時に処理することが可能であり、必要です。 最も簡単なオプションは複数のデーモンを実行することですが、これにより同期の問題が発生します。 複数のプロセスが同時に1つのファイルを処理するとは限りません。 これは、たとえば、対応するフラグ(Video :: PROCESSING_STATE)を設定してデータベース内のレコードを「ブロック」することで解決できます。
ただし、処理が1つのサーバーでのみ発生する場合は、よりスマートに実行できます。メインデーモンでスレッドを作成します。
これらの目的には、 spawnプラグインが適しています。これにより、ストリームを簡単に作成して操作できます。 これで、デーモンは一度に複数のオブジェクトを選択し、それらを別々のスレッドで処理します。
lib / video_converter:
require File.dirname(__FILE__) + '/../config/boot'
require RAILS_ROOT + "/config/environment"
include Spawn
THREAD_COUNT = 5 # ,
SLEEP_TIME = 1
logger = RAILS_DEFAULT_LOGGER
spawn_ids = []
loop do
videos = Video.find(:all, :conditions => {:state => Video::PENDING_STATE}, :order => "id ASC", :limit => THREAD_COUNT)
videos.each_with_index do |video, idx|
logger.info "VideoConverter: convert #{videos.size} videos"
spawn_ids[idx] = spawn do
success = video.process
if success.empty?
video.update_attribute(:state, Video::CONVERTED_STATE)
else
logger.info "VideoConverter: video #{video.id} converting failure"
video.update_attribute(:state, Video::FAILURE_STATE)
end
end
end
wait(spawn_ids)
sleep(SLEEP_TIME)
end
データアプローチは、多くのリソースを消費するタスクに使用できます。
オリジナルは私のブログにあります。