我有一个使用服务的 API,其中我使用 Ruby 线程来减少 API 的响应时间。我尝试使用以下示例共享上下文。它在 Rails 4、ruby 2.2.1 上运行良好
现在,我们已将 rails 升级到 5.2.3 和 ruby 2.6.5。之后服务停止工作。我可以从控制台调用服务,它工作正常。但是通过 API 调用,服务一旦到达 CurrencyConverter.new 就会变得无响应。任何想法可能是什么问题?
class ParallelTest
def initialize
puts "Initialized"
end
def perform
# Our sample set of currencies
currencies = ['ARS','AUD','CAD','CNY','DEM','EUR','GBP','HKD','ILS','INR','USD','XAG','XAU']
# Create an array to keep track of threads
threads = []
currencies.each do |currency|
# Keep track of the child processes as you spawn them
threads << Thread.new do
puts currency
CurrencyConverter.new(currency).print
end
end
# Join on the child processes to allow them to finish
threads.each do |thread|
thread.join
end
{ success: true }
end
end
class CurrencyConverter
def initialize(params)
@curr = params
end
def print
puts @curr
end
end
如果我删除 CurrencyConverter.new(currency),那么一切正常。CurrencyConverter 是我拥有的服务对象。
发现问题 感谢@anothermh 提供此链接 https://guides.rubyonrails.org/threading_and_code_execution.html#wrapping-application-code https://guides.rubyonrails.org/threading_and_code_execution.html#load-interlock
根据博客,当一个线程通过评估适当文件中的类定义来执行自动加载时,重要的是没有其他线程遇到对部分定义常量的引用。
一次只能加载或卸载一个线程,并且要执行任一操作,它必须等到没有其他线程正在运行应用程序代码。如果一个线程正在等待执行加载,它不会阻止其他线程加载(事实上,它们会合作,并且在所有恢复一起运行之前依次执行其排队的加载)。
这可以通过允许并发加载来解决。 https://guides.rubyonrails.org/threading_and_code_execution.html#permit-concurrent-loads
Rails.application.executor.wrap do
urls.each do |currency|
threads << Thread.new do
CurrencyConverter.new(currency)
puts currency
end
ActiveSupport::Dependencies.interlock.permit_concurrent_loads do
threads.map(&:join)
end
end
end
谢谢大家的时间,我很感激。