我可能会迟到,但无论如何我都会回复,因为其他人可能会偶然发现这个问题。
所以你想要的是可能在一个 Future 完成后立即强制关闭线程池:
class DailyJobs
def call
thread_pool = ::Concurrent::CachedThreadPool.new
jobs = days_to_scan.map{ |day|
Concurrent::Future.execute(executor: thread_pool) do
sleep_time = day.to_f / days_to_scan.count.to_f * seconds_to_complete.to_f
sleep (sleep_time)
if GoogleAPI.new.api_call(@adwords, ad_seeder, visitor, day)
# How to cancel other futures here?
thread_pool.kill
end
end
}
end
end
问题是:实际上并不推荐杀死线程池,并且可能会产生不可预测的结果
更好的方法是跟踪 Future 何时完成并忽略其他 Futures:
class DailyJobs
def call
status = ::Concurrent::AtomicBoolean.new(false)
days_to_scan.map{ |day|
Concurrent::Future.execute do
return if status.true? # Early return so Future does nothing
sleep_time = day.to_f / days_to_scan.count.to_f * seconds_to_complete.to_f
sleep (sleep_time)
if GoogleAPI.new.api_call(@adwords, ad_seeder, visitor, day)
# Do your thing
status.value = true # This will let you know that at least one Future completed
end
end
}
end
end
值得注意的是,如果这是一个 Rails 应用程序,您可能希望包装您的 Future on Rails 执行程序以避免自动加载和死锁问题。我在这里写了