繁体   English   中英

在ruby中并行运行脚本

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM