Ruby on rails 在Ruby中运行线程的链接方法
我有4个需要时间的任务,每个任务取决于前一个任务 e、 g 任务1-克隆git回购 任务2-使用配置文件初始化repo 任务3-处理回购协议 任务4-处理后将结果存储在db中 现在,所有这些任务都将在线程上运行,我正在尝试用不同的方法将所有这4个任务分开,这些方法运行线程并启动任务 我不知道如何将这4种方法链接在一起,但仍然可以从上一种方法得到结果,以便在下一种方法中使用 在方法中分离这些步骤的主要原因是,我可以直接从步骤3开始,在某些情况下完全跳过上一步Ruby on rails 在Ruby中运行线程的链接方法,ruby-on-rails,ruby,multithreading,Ruby On Rails,Ruby,Multithreading,我有4个需要时间的任务,每个任务取决于前一个任务 e、 g 任务1-克隆git回购 任务2-使用配置文件初始化repo 任务3-处理回购协议 任务4-处理后将结果存储在db中 现在,所有这些任务都将在线程上运行,我正在尝试用不同的方法将所有这4个任务分开,这些方法运行线程并启动任务 我不知道如何将这4种方法链接在一起,但仍然可以从上一种方法得到结果,以便在下一种方法中使用 在方法中分离这些步骤的主要原因是,我可以直接从步骤3开始,在某些情况下完全跳过上一步 def clone_repo(url)
def clone_repo(url)
Thread.new do
# clone the repo
# change the status in db
end
end
def init_repo(repo)
Thread.new do
# init config files
# change the status in db
end
end
def process_repo(repo)
Thread.new do
# process repo
# change the status in db
# return or do something with the results to use it in next method
end
end
def store_results(results)
Thread.new do
# store in db
# change the status in db
end
end
我可以朝解决问题的任何方向前进,只需要一种重构的方法来解决这个问题。如果您确实需要在方法内部启动线程(而不是在方法周围,这将使任务更容易),您可以为每个任务使用互斥锁,在相应的任务完成时初始化为锁定和释放,所以,下一个试图在开始时锁定它的依赖线程将等待。 如果不需要任务-只需解锁而不运行 编辑:添加示例结构:
class SomeRepoJob
def perform_in_thread
Thread.new do
perform
end
end
def perform
clone_repo
init_config
results = process_repo
store_results results if results
rescue => e
#do some error reporting if needed
end
private
def set_db_status status
# here you can mark task as "#{status}_started"
yield
# change the status in db
rescue
# revert status on failure
raise
end
def repo_is_cloned?
File.exists?(...)
end
def clone_repo(url)
set_db_status(:cloned){
unless repo_is_cloned?
# clone the repo
end
}
end
def config_exists_and_valid?
File.exists? ...
# some config check and validation
end
def init_config(repo)
set_db_status(:inited_config){
unless config_exists_and_valid?
# init config files
end
}
end
def processed?
# somehow check if processing is needed, or always return false
end
def process_repo(repo)
set_db_status(:processed_not_stored){
unless processed?
# process repo
results
else
results = read_results
end
return results
}
end
def results_stored? results
#...
end
def store_results(results)
set_db_status(:stored_results){
unless results_stored? results
# store in db
end
}
end
end
我可以使用你建议的任何东西,这将有助于完成所需的工作。我建议将可选任务设为幂等(这样即使不需要也可以运行它们-例如克隆任务可以检查repo是否已经存在,等等),并将它们链接到一个线程中,使用我想到的单一入口点,因为我每一步都在改变状态,所以我可以检查一下。但是对于重构代码,我采用了这种方法。无论如何,没有必要让单独的线程永远不能并行运行。那么,如何重构运行线程并执行所有这4项任务的方法呢?因为这肯定会超过100 LOC。