我正在制作一个搜索页面,该页面需要爬网才能获取一些数据。
在前端,用户将单击一个搜索按钮,该按钮将返回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的异步行为。但这也许是唯一的方法吗?
感谢您的帮助!