1. joaoki0412

    No comment

    joaoki0412
Changes in tags
Changes in body
Source | HTML | Preview
@@ -1,9 +1,33 @@
# これは何?
Rails 4.2以降で標準で利用可能になったのがActive Job。
バックグラウンドでジョブを実行するために利用するという理解はしてるけど、実は全然理解できていない人向けです。
+[公式ドキュメント](https://railsguides.jp/active_job_basics.html)はこちらを参照してください。
+
+# そもそもバックグランド処理って何?
+開発するアプリケーションが大規模であればあるほど、
+プログラムの処理に時間がかかるようなことが出て来ると思います。
+(例えば、レコメンド処理の計算とか、何かしらの解析とか)
+
+そういった時間のかかる処理というのを非同期で実行できるようにすることでユーザビリティを向上するのがバックグラウンド処理です。
+
+そのため、バックグラウンド処理で求められる機能は、
+
+- ジョブの登録
+- キューの操作
+ - すぐ実行
+ - 時間おいて実行
+ - 定期実行
+ - 優先度など
+- ジョブの実行
+ - 並列処理など
+- ジョブの失敗時の対応
+ - リトライ
+ - エラー出力など
+
+などなど様々なことが求められます。
# Active Jobって何?
Railsガイドによると、下記のように記載があります。
`Active Job is a new framework in Rails 4.2. It is a common interface on top of queuing systems like Resque, Delayed Job, Sidekiq, and more.`
@@ -18,11 +42,11 @@
## 作成イメージ
下記のようなイメージでコードを作成していきます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/180679/0de61bfc-9d0f-293c-7373-d5b5d8b60336.png)
-ControllerからRedisにジョブが登録されると、
+ControllerからジョブがRedisにキュー登録されると、
ActiveJobをインターフェースとしたSidekiqが常にRedisを監視して新規登録があればジョブを実行するという流れ。
## 詳細
`redis`と `sidekiq`は入れておいてください。
`brew install redis`
@@ -66,10 +90,11 @@
MyJob.set(wait: 3.second).perform_later('Task execute')
render plain: 'success'
end
```
+=> `perform_later`メソッドはJobの`peform`メソッドを呼び出します。
```ruby:routes.rb
post 'start/run'
```
@@ -77,8 +102,35 @@
あとは、Redisの起動、Railsの起動、sidekiqの起動をして、リクエストを投げればsidekiq上で時刻が表示されると思います。
[ほぼこちら](https://dev.classmethod.jp/server-side/ruby-on-rails/ruby-on-rails_active-job-sidekiq/)のコードで勉強させてもらいました。ありがとうございます。
+
# リトライ制御
-ActiveJobはリトライ制御が弱いらしいです。
-WIP
+ActiveJobはリトライ制御が弱いです。
+Rails5.1から`ActiveJob::Base.retry_job`と`ActiveJob::Base.discard_on`というメソッドが追加されたのですが、そこで制御してもSidekiqのリトライ回数などが優先されてしまいます。
+[Rails5.1のリリースノート](https://railsguides.jp/5_1_release_notes.html#active-job)
+
+ここで、リトライ回数を制御する必要性が出て来るわけです。
+僕が色々試した中で最も良かったのは、[activejob-retry](https://github.com/isaacseymour/activejob-retry)というgemの利用です。
+
+gemをインストールした後は、制御したいジョブクラスの中で下記のように宣言すれば制御可能です。
+
+```ruby:my_job.rb
+queue_as :default
+
+include ActiveJob::Retry.new(strategy: :constant, limit: 3, delay: 3.seconds)
+
+rescue_from(StandardError) do
+ p("All Retry Failed")
+end
+
+def perform(message)
+ p("Time:#{Time.now}:#{message}")
+ error #エラーを起こすためわざと宣言してない変数を置いてます。
+end
+```
+
+実行してみた感じ、きちっと3秒おきに実行されるわけではない(誰かわかる方ぜひ教えてくださいませ)のですが、
+今回の目的であったリトライ回数に関してはしっかりと達成されていました。
+
+導入も簡単なのでこちらで試してみるのがいいかもしれません。