如何取消忙碌的Sidekiq工作人员,以便使与池的某些连接保持打开状态?

时间:2019-07-17 19:40:13

标签: ruby-on-rails redis sidekiq

我正在制作一个搜索页面,该页面需要爬网才能获取一些数据。

在前端,用户将单击一个搜索按钮,该按钮将返回9个信息块。这9个磁贴具有我存储在postgres数据库中的基本数据。渲染完这9个图块之后,我请求获取填充其余图块所需的数据,即需要爬网的数据。

在我的search controller中,为每个图块启动Sidekiq工作器CrawlWorker.perform_async(args)

tiles.each{ |args| 
  CrawlWorker.perform_async(args)

我遇到的问题是用户更改搜索的时间。这将渲染9个新的图块,然后将开始一组新的CrawlWorkers。问题是上一次搜索中的CrawlWorkers中的某些仍在运行。如果一次运行太多,我将得到#<ActiveRecord::ConnectionTimeoutError: could not obtain a connection from the pool within 5.000 seconds (waited 5.003 seconds); all pooled connections were in use>

我已尝试通过search_controller中的类似方式取消我的CrawlWorker

CrawlWorker.cancel!(jid)

以及我的工作文件中的以下内容:

def cancelled?
  Sidekiq.redis {|c| c.exists("cancelled-#{jid}") }
end

def self.cancel!(jid)=
  Sidekiq.redis {|c| c.setex("cancelled-#{jid}", 86400, 1) }
end

def perform(args)
  return if cancelled?

当我从cancel调用search_controller方法时,似乎这些工人实际上并没有取消,并且我还遇到以下错误:     错误:提取作业时出错:连接超时     警告:Redis :: TimeoutError:连接超时

我的目标是以某种方式清除旧搜索中的爬网,因为它们不再与用户相关。我希望尽快取消这些爬网,以使池不会因新请求而超载。做这个的最好方式是什么?

我当时想我可以将作业添加到Sidekiq队列中,然后一个接一个地执行-如果用户进行新搜索,则可以清除队列。问题是我无法利用Sidekiq的异步行为。但这也许是唯一的方法吗?

感谢您的帮助!

0 个答案:

没有答案