新手问题 怎么继续某个 Rake Task?

cqcn1991 · 2015年06月25日 · 最后由 rei 回复于 2015年06月26日 · 1878 次阅读

比如说,我想给所有的article抓 SNS 上的数据

articles = Article.all
 articles.each do |article|
   get_share(article)  #use HTTParty, Nokogiri, etc.
   if article.save
     puts "#{article.url}, #{article.share}"
   end
 end

但有时候会报错,可能网断了,或者文章地址有问题,或者怎样 这个时候,就会报错退出。要再来的话,就只能从头开始,这样挺浪费时间的

不知道怎么可以“从上次出错的article重新开始?

Stackoverflow 同步贴:http://stackoverflow.com/questions/31031607/rails-how-to-resume-a-rake-task/31031977#31031977

  1. 事务,一个也别进去
  2. 文章应该有一个唯一的标题吧,或者其他唯一标志,查出来从下一个开始

这个肯定要添加异常处理,如果断网或者地址出错,肯定会有超时之类的错误,你可以捕获异常进行处理,比如记下当前的标题或数组下标。如果你可以忍受某个文章数据异常,那就跳过这次,不用直接退出程序,而是从下个文章继续。

如果你的 articles 数量比较大的话,用多线程去跑会更节省时间。

是否可以考虑改成独立的任务去跑,比如放到 sidekiq 里去,每个 article 一个 sidekiq 任务,这样单个任务失败可以重试,不影响其他任务结果

文章的 id,或者干脆网址,你在你的 article 里面记录一下 refer url,每次去判断一下也可以,如果只是纯抓数据, #4 楼这方法也挺粗暴的 😄

#5 楼 @zoker 这方法不粗暴,放到任务队列可以并行执行。

#6 楼 @rei 😄 并行十个的话,单个 IP 来说,够粗暴了,很容易被网站封。

#7 楼 @zoker 放到队列可以分布到多个机器执行,不同的目标设置不同的暂停时间。

队列有很多优化余地,想仿照原先的行为用一个 worker 就行了,额外获得了任务隔离和重试的能力。这是更精细了,不是粗暴。

#8 楼 @rei 额外获得了任务隔离和重试的能力 👏

#9 楼 @zoker 这是讽刺吗?

#10 楼 @rei 这是赞同,没有任何讽刺的意思。

#11 楼 @zoker 那我误会了。

需要 登录 后方可回复, 如果你还没有账号请 注册新账号