<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>leekelby (真宽)</title>
    <link>https://ruby-china.org/leekelby</link>
    <description>has_many :bugs, through: :rails, source: :ruby</description>
    <language>en-us</language>
    <item>
      <title>[已解决] ActiveJob + Sidekiq 报错，uninitialized constant 怎么解决？</title>
      <description>&lt;p&gt;A NameError occurred in background at 2016-02-23 16:57:48 +0800 :&lt;/p&gt;

&lt;p&gt;uninitialized constant DetectFamousAndMajorJob
  /home/deployer/apps/app_name/shared/bundle/ruby/2.1.0/gems/activesupport-4.2.5/lib/active_support/inflector/methods.rb:261:in `const_get'&lt;/p&gt;

&lt;hr&gt;
&lt;h2 id="Backtrace:"&gt;Backtrace:&lt;/h2&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/home/deployer/apps/app_name/shared/bundle/ruby/2.1.0/gems/activesupport-4.2.5/lib/active_support/inflector/methods.rb:261:in `const_get'
/home/deployer/apps/app_name/shared/bundle/ruby/2.1.0/gems/activesupport-4.2.5/lib/active_support/inflector/methods.rb:261:in `block in constantize'
/home/deployer/apps/app_name/shared/bundle/ruby/2.1.0/gems/activesupport-4.2.5/lib/active_support/inflector/methods.rb:259:in `each'
/home/deployer/apps/app_name/shared/bundle/ruby/2.1.0/gems/activesupport-4.2.5/lib/active_support/inflector/methods.rb:259:in `inject'
/home/deployer/apps/app_name/shared/bundle/ruby/2.1.0/gems/activesupport-4.2.5/lib/active_support/inflector/methods.rb:259:in `constantize'
/home/deployer/apps/app_name/shared/bundle/ruby/2.1.0/gems/activesupport-4.2.5/lib/active_support/core_ext/string/inflections.rb:66:in `constantize'
/home/deployer/apps/app_name/shared/bundle/ruby/2.1.0/gems/activejob-4.2.5/lib/active_job/core.rb:28:in `deserialize'
/home/deployer/apps/app_name/shared/bundle/ruby/2.1.0/gems/activejob-4.2.5/lib/active_job/execution.rb:20:in `execute'
/home/deployer/apps/app_name/shared/bundle/ruby/2.1.0/gems/activejob-4.2.5/lib/active_job/queue_adapters/sidekiq_adapter.rb:42:in `perform'
/home/deployer/apps/app_name/shared/bundle/ruby/2.1.0/gems/sidekiq-4.0.2/lib/sidekiq/processor.rb:150:in `execute_job'
/home/deployer/apps/app_name/shared/bundle/ruby/2.1.0/gems/sidekiq-4.0.2/lib/sidekiq/processor.rb:132:in `block (2 levels) in process'
/home/deployer/apps/app_name/shared/bundle/ruby/2.1.0/gems/sidekiq-4.0.2/lib/sidekiq/middleware/chain.rb:127:in `block in invoke'
/home/deployer/apps/app_name/shared/bundle/ruby/2.1.0/gems/exception_notification-4.0.1/lib/exception_notification/sidekiq.rb:8:in `call'
/home/deployer/apps/app_name/shared/bundle/ruby/2.1.0/gems/sidekiq-4.0.2/lib/sidekiq/middleware/chain.rb:129:in `block in invoke'
/home/deployer/apps/app_name/shared/bundle/ruby/2.1.0/gems/newrelic_rpm-3.14.1.311/lib/new_relic/agent/instrumentation/sidekiq.rb:33:in `block in call'
/home/deployer/apps/app_name/shared/bundle/ruby/2.1.0/gems/newrelic_rpm-3.14.1.311/lib/new_relic/agent/instrumentation/controller_instrumentation.rb:362:in `perform_action_with_newrelic_trace'
/home/deployer/apps/app_name/shared/bundle/ruby/2.1.0/gems/newrelic_rpm-3.14.1.311/lib/new_relic/agent/instrumentation/sidekiq.rb:29:in `call'
/home/deployer/apps/app_name/shared/bundle/ruby/2.1.0/gems/sidekiq-4.0.2/lib/sidekiq/middleware/chain.rb:129:in `block in invoke'
/home/deployer/apps/app_name/shared/bundle/ruby/2.1.0/gems/sidekiq-4.0.2/lib/sidekiq/middleware/server/active_record.rb:6:in `call'
/home/deployer/apps/app_name/shared/bundle/ruby/2.1.0/gems/sidekiq-4.0.2/lib/sidekiq/middleware/chain.rb:129:in `block in invoke'
/home/deployer/apps/app_name/shared/bundle/ruby/2.1.0/gems/sidekiq-4.0.2/lib/sidekiq/middleware/server/retry_jobs.rb:74:in `call'
/home/deployer/apps/app_name/shared/bundle/ruby/2.1.0/gems/sidekiq-4.0.2/lib/sidekiq/middleware/chain.rb:129:in `block in invoke'
/home/deployer/apps/app_name/shared/bundle/ruby/2.1.0/gems/sidekiq-4.0.2/lib/sidekiq/middleware/server/logging.rb:11:in `block in call'
/home/deployer/apps/app_name/shared/bundle/ruby/2.1.0/gems/sidekiq-4.0.2/lib/sidekiq/logging.rb:30:in `with_context'
/home/deployer/apps/app_name/shared/bundle/ruby/2.1.0/gems/sidekiq-4.0.2/lib/sidekiq/middleware/server/logging.rb:7:in `call'
/home/deployer/apps/app_name/shared/bundle/ruby/2.1.0/gems/sidekiq-4.0.2/lib/sidekiq/middleware/chain.rb:129:in `block in invoke'
/home/deployer/apps/app_name/shared/bundle/ruby/2.1.0/gems/sidekiq-4.0.2/lib/sidekiq/middleware/chain.rb:132:in `call'
/home/deployer/apps/app_name/shared/bundle/ruby/2.1.0/gems/sidekiq-4.0.2/lib/sidekiq/middleware/chain.rb:132:in `invoke'
/home/deployer/apps/app_name/shared/bundle/ruby/2.1.0/gems/sidekiq-4.0.2/lib/sidekiq/processor.rb:127:in `block in process'
/home/deployer/apps/app_name/shared/bundle/ruby/2.1.0/gems/sidekiq-4.0.2/lib/sidekiq/processor.rb:166:in `stats'
/home/deployer/apps/app_name/shared/bundle/ruby/2.1.0/gems/sidekiq-4.0.2/lib/sidekiq/processor.rb:126:in `process'
/home/deployer/apps/app_name/shared/bundle/ruby/2.1.0/gems/sidekiq-4.0.2/lib/sidekiq/processor.rb:79:in `process_one'
/home/deployer/apps/app_name/shared/bundle/ruby/2.1.0/gems/sidekiq-4.0.2/lib/sidekiq/processor.rb:67:in `run'
/home/deployer/apps/app_name/shared/bundle/ruby/2.1.0/gems/sidekiq-4.0.2/lib/sidekiq/util.rb:16:in `watchdog'
/home/deployer/apps/app_name/shared/bundle/ruby/2.1.0/gems/sidekiq-4.0.2/lib/sidekiq/util.rb:24:in `block in safe_thread'
&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h2 id="Data:"&gt;Data:&lt;/h2&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="ss"&gt;data: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:sidekiq&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"class"&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="s2"&gt;"ActiveJob::QueueAdapters::SidekiqAdapter::JobWrapper"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="s2"&gt;"wrapped"&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="s2"&gt;"DetectFamousAndMajorJob"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="s2"&gt;"queue"&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="s2"&gt;"default"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="s2"&gt;"args"&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="s2"&gt;"job_class"&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="s2"&gt;"DetectFamousAndMajorJob"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"job_id"&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="s2"&gt;"d4b06924-41a6-4b5a-bd78-9c1fb698769f"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"queue_name"&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="s2"&gt;"default"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"arguments"&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;6601&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="s2"&gt;"locale"&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="s2"&gt;"zh-CN"&lt;/span&gt;&lt;span class="p"&gt;}],&lt;/span&gt;
   &lt;span class="s2"&gt;"retry"&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="s2"&gt;"jid"&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="s2"&gt;"8043b8395a79fcb69739ed38"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="s2"&gt;"created_at"&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="mf"&gt;1456217431.8794465&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="s2"&gt;"enqueued_at"&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="mf"&gt;1456217868.0243142&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="s2"&gt;"error_message"&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="s2"&gt;"uninitialized constant DetectFamousAndMajorJob"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="s2"&gt;"error_class"&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="s2"&gt;"NameError"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="s2"&gt;"failed_at"&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="mf"&gt;1456217439.976102&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="s2"&gt;"retry_count"&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="s2"&gt;"retried_at"&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="mf"&gt;1456217663.7122743&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h2 id="其它:"&gt;其它：&lt;/h2&gt;
&lt;p&gt;任务是脚本生成的：&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rails g DetectFamousAndMajorJob
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;配置&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# config/environments/production.rb&lt;/span&gt;
  &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cache_classes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;

  &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;eager_load&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#   config/sidekiq.yml
---
:verbose: false
:pidfile: ./tmp/pids/sidekiq.pid
:concurrency: 5
:timeout: 30
:queues:
  - default
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;邮件里经常有类似报错，一般 retry 几次就过了，但看着太烦了。可能是什么原因引起的，怎么解决？&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;一些 redis/sidekiq 配置问题，已解决&lt;/strong&gt;&lt;/p&gt;</description>
      <author>leekelby</author>
      <pubDate>Wed, 24 Feb 2016 11:51:48 +0800</pubDate>
      <link>https://ruby-china.org/topics/29076</link>
      <guid>https://ruby-china.org/topics/29076</guid>
    </item>
    <item>
      <title>Rails 4-2-stable 参考手册 (Beta)</title>
      <description>&lt;p&gt;花了一年多时间，断断续续写了一本 Rails 方面的书，现在分享出来。书名暂定为“Rails 4-2-stable 参考手册 (Beta)”。因为写书过程中，基本上阅读的都是 Rails 4-2-stable 分支的源代码；并且有很多错漏需要更改，所以这次发布的是 Beta 版本，意思就是后续我还会改的。&lt;/p&gt;

&lt;p&gt;为什么叫参考手册呢？本书主要包括两部分“Rails 源码剖析和 Rails 使用指南”，因为我想不出一个合适的名字来同时表现它们。Rails 是一个 Web 开发框架，也是一个工具。"工欲善其事必先利其器"，想要更好的使用 Rails 这个工具，清楚其背后的魔法，阅读源代码是必备功课。&lt;/p&gt;

&lt;p&gt;本书尽量做到系统、全面，从源码出发，会讲解到原理。本书大部分内容为原创，少数内容为整理网上资料，鉴于参考资料太多，恕我不能一一列举来源。后续我尽量找出涉及版权问题的部分章节，然后进行重写或删除。&lt;/p&gt;
&lt;h4 id="本书适合什么样的读者？"&gt;本书适合什么样的读者？&lt;/h4&gt;
&lt;p&gt;想要更好的使用 Rails
准备阅读 Rails 的源代码
想知道 Rails 的整体架构
想清楚 Rails 背后的魔法&lt;/p&gt;
&lt;h4 id="本书包含了哪些内容？"&gt;本书包含了哪些内容？&lt;/h4&gt;
&lt;p&gt;一些文档里找不到的方法
每个模块的关键所在
源码阅读路线图&lt;/p&gt;
&lt;h4 id="本书不讲哪些内容？"&gt;本书不讲哪些内容？&lt;/h4&gt;
&lt;p&gt;安装、部署
奇技淫巧
Ruby 语法、Rails 入门
和具体业务相关的问题或功能
非常具体、底层的代码实现&lt;/p&gt;
&lt;h4 id="联系我"&gt;联系我&lt;/h4&gt;
&lt;p&gt;邮箱：leekelby@gmail.com
QQ 群：397935907&lt;/p&gt;

&lt;p&gt;初衷：自己使用 Rails 已经有几年时间了，我一直想对它有个全面、系统的了解。所以写整理、编写了这本书，供自己学习和使用，尽量做到全面、系统，有讲概念，有讲原理。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;如果您阅读后，发现错误或要改进的点，请联系我反馈；觉得对自己或他人有用的，可以分享或转发，希望能够对更多人有帮助。&lt;/strong&gt;
谢谢。&lt;/p&gt;
&lt;h4 id="链接："&gt;链接：&lt;/h4&gt;
&lt;p&gt;&lt;a href="https://www.gitbook.com/book/kelby/rails-beginner-s-guide/details" rel="nofollow" target="_blank" title=""&gt;Rails 4-2-stable 参考手册 (Beta)&lt;/a&gt;&lt;/p&gt;
&lt;h4 id="涉及内容"&gt;涉及内容&lt;/h4&gt;
&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/2015/a5021525c9ffa3cd11877ec7479c35ab.png" title="" alt=""&gt;&lt;/p&gt;

&lt;hr&gt;

&lt;p&gt;为自己的创业项目打个广告 Power by &lt;a href="http://shixian.com?from=ruby-china" rel="nofollow" target="_blank" title=""&gt;shixian.com&lt;/a&gt;&lt;/p&gt;</description>
      <author>leekelby</author>
      <pubDate>Mon, 17 Aug 2015 09:48:55 +0800</pubDate>
      <link>https://ruby-china.org/topics/26954</link>
      <guid>https://ruby-china.org/topics/26954</guid>
    </item>
    <item>
      <title>Rails 4.2 新增后端任务框架 - Active Job</title>
      <description>&lt;p&gt;&lt;strong&gt;不同的延迟任务，一样的 API.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;在 Delayed Job、Resque、Sidekiq 等延迟任务之间切换，还要改代码？
以后就不必了...&lt;/p&gt;

&lt;p&gt;虽然这几个延迟任务 gem 使用上类似，但语法上多少有一点不同。
新的 ActiveJob 组件统一了接口，使用和切换都会变得更容易。&lt;/p&gt;
&lt;h2 id="Queue Adapter"&gt;Queue Adapter&lt;/h2&gt;
&lt;p&gt;默认使用的 queue_adapter 是 :inline，你可以根据需要自己设置 queue_adapter.&lt;/p&gt;

&lt;p&gt;已经支持 Delayed Job、Resque、Sidekiq 等常用延迟任务 gem.&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# 默认 queue adapter&lt;/span&gt;
&lt;span class="no"&gt;ActiveJob&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Base&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;queue_adapter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="ss"&gt;:inline&lt;/span&gt;
&lt;span class="c1"&gt;# 或&lt;/span&gt;
&lt;span class="no"&gt;Rails&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;application&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;active_job&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;queue_adapter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="ss"&gt;:test&lt;/span&gt;

&lt;span class="c1"&gt;# 所有可用 adapter: :backburner, :delayed_job, :qu, :que, &lt;/span&gt;
&lt;span class="c1"&gt;# :queue_classic, :resque, :sidekiq, :sneakers, :sucker_punch, :inline, :test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="Queue Name"&gt;Queue Name&lt;/h2&gt;
&lt;p&gt;默认使用的 queue_name 是 "default"&lt;/p&gt;

&lt;p&gt;可以定制：&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyJob&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ActiveJob&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Base&lt;/span&gt;
  &lt;span class="n"&gt;queue_as&lt;/span&gt; &lt;span class="ss"&gt;:my_jobs&lt;/span&gt;

  &lt;span class="c1"&gt;# ...&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;通过 &lt;code&gt;config.active_job.queue_name_prefix=&lt;/code&gt; 可给所有队列名加前缀。&lt;/p&gt;
&lt;h2 id="Core"&gt;Core&lt;/h2&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# 实例方法
serialize

# 类方法
set # 常用
deserialize
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;使用举例：&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Enqueue a job to be performed as soon the queueing system is free.&lt;/span&gt;
&lt;span class="no"&gt;MyJob&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;perform_later&lt;/span&gt; &lt;span class="n"&gt;record&lt;/span&gt;

&lt;span class="c1"&gt;# Enqueue a job to be performed tomorrow at noon.&lt;/span&gt;
&lt;span class="no"&gt;MyJob&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;wait_until: &lt;/span&gt;&lt;span class="no"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;tomorrow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;noon&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;perform_later&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;record&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Enqueue a job to be performed 1 week from now.&lt;/span&gt;
&lt;span class="no"&gt;MyJob&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;wait: &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;week&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;perform_later&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;record&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="Enqueuing 入队与重试"&gt;Enqueuing 入队与重试&lt;/h2&gt;
&lt;p&gt;常用方法：&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;enqueue
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;使用举例：&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;my_job_instance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;enqueue&lt;/span&gt;

&lt;span class="c1"&gt;# 目前，只接受以下 3 种参数&lt;/span&gt;
&lt;span class="n"&gt;my_job_instance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;enqueue&lt;/span&gt; &lt;span class="ss"&gt;wait: &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;minutes&lt;/span&gt;
&lt;span class="n"&gt;my_job_instance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;enqueue&lt;/span&gt; &lt;span class="ss"&gt;queue: :important&lt;/span&gt;
&lt;span class="n"&gt;my_job_instance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;enqueue&lt;/span&gt; &lt;span class="ss"&gt;wait_until: &lt;/span&gt;&lt;span class="no"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;tomorrow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;midnight&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;执行任务失败，还可以：&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;retry_job&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;使用举例：&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SiteScrapperJob&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ActiveJob&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Base&lt;/span&gt;
  &lt;span class="n"&gt;rescue_from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;ErrorLoadingSite&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;retry_job&lt;/span&gt; &lt;span class="ss"&gt;queue: :low_priority&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;perform&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;# raise ErrorLoadingSite if cannot scrape&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;除上述两实例方法外，还有类方法：&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;perform_later
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="Execution 执行"&gt;Execution 执行&lt;/h2&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# 实例方法&lt;/span&gt;
&lt;span class="n"&gt;perform&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;perform_now&lt;/span&gt;

&lt;span class="c1"&gt;# 类方法&lt;/span&gt;
&lt;span class="n"&gt;perform_now&lt;/span&gt; &lt;span class="c1"&gt;# 简单封装了实例方法 perform_now&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;使用举例：&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;MyJob&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;perform_now&lt;/span&gt;

&lt;span class="no"&gt;MyJob&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;perform_now&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"mike"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="Callbacks 回调"&gt;Callbacks 回调&lt;/h2&gt;
&lt;p&gt;比某些延迟 gem 多做了一点点，除了队列&amp;amp;执行本身外，还可以有回调：&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;before_enqueue&lt;/span&gt;
&lt;span class="n"&gt;around_enqueue&lt;/span&gt;
&lt;span class="n"&gt;after_enqueue&lt;/span&gt;

&lt;span class="n"&gt;before_perform&lt;/span&gt;
&lt;span class="n"&gt;around_perform&lt;/span&gt;
&lt;span class="n"&gt;after_perform&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;使用举例：&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;VideoProcessJob&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ActiveJob&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Base&lt;/span&gt;
  &lt;span class="n"&gt;queue_as&lt;/span&gt; &lt;span class="ss"&gt;:default&lt;/span&gt;

  &lt;span class="n"&gt;after_perform&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;job&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="no"&gt;UserMailer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;notify_video_processed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;job&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;first&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;perform&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;video_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="no"&gt;Video&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;video_id&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;process&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;其它几个方法类似。&lt;/p&gt;

&lt;p&gt;实现上，都是直接封装 &lt;code&gt;set_callback&lt;/code&gt;&lt;/p&gt;
&lt;h2 id="提示"&gt;提示&lt;/h2&gt;
&lt;p&gt;有利必有弊，可能面临以下问题：&lt;br&gt;
原 gem 本身的特点没能充分利用，灵活性降低，和其它 gem 的集成会变复杂。&lt;/p&gt;

&lt;p&gt;---------------------------------------------------------------- 分隔线 ----------------------------------------------------------------&lt;/p&gt;

&lt;p&gt;其它多个类或模块，统一在此列举。&lt;/p&gt;
&lt;h2 id="Arguments 参数处理"&gt;Arguments 参数处理&lt;/h2&gt;
&lt;p&gt;接受的参数类型很广泛，需要先处理一下。&lt;/p&gt;

&lt;p&gt;进队列时参数需要 serialize，
执行前参数需要 deserialize&lt;/p&gt;

&lt;p&gt;当然，这都是自动完成的。&lt;/p&gt;
&lt;h2 id="参数支持 Global ID"&gt;参数支持 Global ID&lt;/h2&gt;
&lt;p&gt;一般入队列 (enqueue_in、enqueue_at 和 enqueue) 只传能够标识对象的那部分参数 (如：class、id)，出队列/执行的时候再根据这些参数获取对象。&lt;/p&gt;

&lt;p&gt;但因为 serialize_argument 支持的类型有多种，其中就包括 GlobalID::Identification. 所以我们可以传递一个"活的对象"进队列，而不只是它的一部分 (如：class、id).&lt;/p&gt;

&lt;p&gt;使用 Global ID 前后对比：&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TrashableCleanupJob&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;perform&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;trashable_class&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;trashable_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;depth&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;# 出队列/执行的时候需要根据 trashable_class 和 trashable_id 查询相应 trashable&lt;/span&gt;
    &lt;span class="n"&gt;trashable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;trashable_class&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;constantize&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;trashable_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;trashable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cleanup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;depth&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TrashableCleanupJob&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;perform&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;trashable&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;depth&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;# 出队列/执行的时候直接使用 trashable&lt;/span&gt;
    &lt;span class="n"&gt;trashable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cleanup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;depth&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;Note: 不规范的写法里，也可以直接传递对象。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="Railtie"&gt;Railtie&lt;/h2&gt;
&lt;p&gt;设置 logger 和配置 (如：默认 queue_adapter)&lt;/p&gt;
&lt;h2 id="Queue Adapters"&gt;Queue Adapters&lt;/h2&gt;
&lt;p&gt;原来，不同的延迟任务 gem 有各自不同的 self.perform、perform、run、work，现在：&lt;/p&gt;

&lt;p&gt;都有同名的 self.enqueue 和 self.enqueue_at&lt;/p&gt;
&lt;h2 id="Logging"&gt;Logging&lt;/h2&gt;
&lt;p&gt;around_enqueue、around_perform 和 before_enqueue 有日志记录&lt;/p&gt;

&lt;p&gt;enqueue、enqueue_at、perform_start、perform 等过程也有日志记录&lt;/p&gt;
&lt;h2 id="Identifier"&gt;Identifier&lt;/h2&gt;
&lt;p&gt;每个任务都有全局唯一的 job_id&lt;/p&gt;
&lt;h2 id="Configured Job"&gt;Configured Job&lt;/h2&gt;
&lt;p&gt;配置实例，对应着 Core 的 set 类方法。&lt;/p&gt;
&lt;h2 id="解析 queue_adapter 及其 API"&gt;解析 queue_adapter 及其 API&lt;/h2&gt;
&lt;p&gt;queue_adapter 是 Delayed Job、Resque、Sidekiq 等不同的延迟任务抽象而来。&lt;/p&gt;

&lt;p&gt;而 queue_adapter 所用的 API(enqueue_at、enqueue_in、enqueue 等)，也是从原延迟任务所提供的 API 抽象而来。&lt;/p&gt;
&lt;h2 id="命令行快捷生成"&gt;命令行快捷生成&lt;/h2&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;rails generate job NAME &lt;span class="o"&gt;[&lt;/span&gt;options]
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="异常捕获与处理"&gt;异常捕获与处理&lt;/h2&gt;
&lt;p&gt;使用 ActiveSupport 的异常捕获方法 &lt;code&gt;rescue_from&lt;/code&gt;&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;GuestsCleanupJob&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ActiveJob&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Base&lt;/span&gt;
  &lt;span class="n"&gt;queue_as&lt;/span&gt; &lt;span class="ss"&gt;:default&lt;/span&gt;

  &lt;span class="c1"&gt;# 异常捕获&lt;/span&gt;
  &lt;span class="n"&gt;rescue_from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;ActiveRecord&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;RecordNotFound&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;exception&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
   &lt;span class="c1"&gt;# 异常处理&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;perform&lt;/span&gt;
    &lt;span class="c1"&gt;# ...&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;</description>
      <author>leekelby</author>
      <pubDate>Mon, 18 Aug 2014 19:03:39 +0800</pubDate>
      <link>https://ruby-china.org/topics/21092</link>
      <guid>https://ruby-china.org/topics/21092</guid>
    </item>
    <item>
      <title>学习，使用 git 过程中做的思维导图</title>
      <description>&lt;p&gt;这是学习，使用 git 过程中做的思维导图，分享出来给大家。&lt;/p&gt;

&lt;p&gt;用的是 XMind 画的，如果你恰好装有此软件，或者能打开 .xmind 格式的软件，可以直接从网盘下载源文件。
&lt;a href="http://yunpan.cn/Q4rwFTXLqhe42" rel="nofollow" target="_blank"&gt;http://yunpan.cn/Q4rwFTXLqhe42&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;你也可以直接查看生成的图片，直接或者浏览 &lt;a href="http://yunpan.cn/Q4rwyzZW6GTMT" rel="nofollow" target="_blank" title=""&gt;网盘链接&lt;/a&gt; 源图片&lt;/p&gt;

&lt;p&gt;主要包括：安装配置，基本概念，常用命令 (基础)，命令集 (中级)，一直开发流程，一些使用场景。
内容部分来源于网络整理，参考较多的都给出来源，部分是自己的使用经验。&lt;/p&gt;

&lt;p&gt;包含内容
&lt;img src="//l.ruby-china.com/photo/2014/4597b199ed94636f7904aa83d3e48bd4.png" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;基本概念
&lt;img src="//l.ruby-china.com/photo/2014/fb5efd5edf8eab33c0d9706eb38ffe82.png" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;基本配置
&lt;img src="//l.ruby-china.com/photo/2014/1ad9da1db28f1da5a05c6f64d61d5bf6.png" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;命令的基本使用
&lt;img src="//l.ruby-china.com/photo/2014/2644877e681b0fcaf4e2d8c08917710d.png" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;命令集
&lt;img src="//l.ruby-china.com/photo/2014/bb584129ce5c271f07a21ed84235353c.png" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;场景
&lt;img src="//l.ruby-china.com/photo/2014/2d5e383e70457e4f1f41fb4c4101f48a.png" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;git 使用灵活，要达到一样的目的，通常都有好几种做法。所以…&lt;/p&gt;

&lt;p&gt;最后说明一下，这份思维导图会一直更新的。分享出来也是为了做得更好，欢迎反馈，或者提交 merge request。
&lt;a href="https://gitcafe.com/restkuan/git" rel="nofollow" target="_blank"&gt;https://gitcafe.com/restkuan/git&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;感谢 gitcafe，方便了我在家里和办公室之间切换，以及省去上传网盘的来回复制粘贴。 &lt;img title=":disappointed_relieved:" alt="😥" src="https://twemoji.ruby-china.com/2/svg/1f625.svg" class="twemoji"&gt;&lt;/p&gt;</description>
      <author>leekelby</author>
      <pubDate>Sat, 01 Mar 2014 14:26:13 +0800</pubDate>
      <link>https://ruby-china.org/topics/17590</link>
      <guid>https://ruby-china.org/topics/17590</guid>
    </item>
  </channel>
</rss>
