[英]Run scripts in parallel in ruby
我需要将视频转换为4个线程
例如,我有Active Record模型视频,其标题为:Video1,Video2,Video3,Video4,Video5
所以,我需要执行这样的事情
bundle exec script/video_converter start
例如,其中脚本将处理4个线程的未转换视频
Video.where(state: 'unconverted').first.process
但是,如果要转换4个视频之一,则必须将下一个视频自动添加到主题中
最好的解决方案是什么? Sidekiq宝石? 守护程序gem + Ruby线程手动?
现在,我正在使用此脚本:
THREAD_COUNT = 4
SLEEP_TIME = 5
logger = CONVERTATION_LOG
spawns = []
loop do
videos = Video.where(state:'unconverted').limit(THREAD_COUNT).reorder("ID DESC")
videos.each do |video|
spawns << Spawnling.new do
result = video.process
if result.nil?
video.create_thumbnail!
else
video.failured!
end
end
end
Spawnling.wait(spawns)
sleep(SLEEP_TIME)
end
但是此脚本会等待4个视频,之后又需要另外4个视频。 我希望在转换完第4个视频之一之后,它将自动添加到新线程中,该线程为空。
如果您的目标是仅使用4个线程(或配置为使用Spawnling的任何版本-因为它支持fork和thread)来继续处理视频,则可以使用Queue来排队要处理的所有视频记录,生成4个线程并让他们一直处理记录,直到队列为空。
require "rails"
require "spawnling"
# In your case, videos are read from DB, below array is for illustration
videos = ["v1", "v2", "v3", "v4", "v5", "v6", "..."]
THREAD_COUNT = 4
spawns = []
q = Queue.new
videos.each {|i| q.push(i) }
THREAD_COUNT.times do
spawns << Spawnling.new do
until q.empty? do
v = q.pop
# simulate processing
puts "Processing video #{v}"
# simulate processing time
sleep(rand(10))
end
end
end
Spawnling.wait(spawns)
这个答案的灵感来自这个答案
PS:我添加了一些要求并定义了videos
数组,以使上面的代码自成体系地运行示例。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.