gem Sidekiqの導入

## Sidekiqとは？
非同期処理を実行する時に使用するgemです。[公式ドキュメント](https://github.com/mperham/sidekiq)（の日本語訳）によると、得られるメリットはこちら。

> Rubyのシンプルで効率的なバックグラウンド処理。 Sidekiqはスレッドを使用して、同じプロセスで同時に多くのジョブを処理します。 Railsは必要ありませんが、Railsと緊密に統合され、バックグラウンド処理が非常に簡単になります。

今回は、Railsの課題を実施していく中で`sidekiq`を使いましょうとの指定があったので、それに沿って実装をしていきます。

## 非同期処理とは？

そもそも「非同期処理」というものがよく分かっていなかったのですが、[こちらの記事](https://qiita.com/nichenri1995/items/d66b055b09398483fa5b)で丁寧に解説されていました。

> 簡単に言ってしまえば時間のかかる処理を、通常の処理とは別に、「あとで処理しますよリスト」に登録すること。要はあるタスクを実行している間に他のタスクを実行できる、ということ。逆は"同期処理"とよばれ、あるタスクが実行されている間、他のタスクはできない。

> 時間のかかる処理の例: メール送信・ファイルのダウンロード・アップロードなど

なるほどです。。。。。なお、非同期処理を行うことのメリットは、[こちらの記事](https://qiita.com/yumiyon/items/6835d90e621e73268021)によると「複数のジョブを同時に実行することにより、メモリを節約すること可能です。」だそうです。

そういえば、公式サイトにはパフォーマンスに関する記述が情報に大きく書いてありますね。。。
[![Image from Gyazo](https://i.gyazo.com/82d49fd6802efa2eb06c4388cc881bd9.png)](https://gyazo.com/82d49fd6802efa2eb06c4388cc881bd9)

ちなみに、同様の働きをするGem(?)に、

- Delayed Job
- Resque

などがあるらしいです。

## 導入
さて、導入です。まず、`Gemfile`に以下のように記載し、

```ruby:Gemfile
gem 'sidekiq'
```
`bundle install`します。

次に、`config/application.rb`に下記のように設定します。

```ruby:config/application.rb
module YourAppName
  class Application < Rails::Application
    # 中略
    config.active_job.queue_adapter = :sidekiq
  end
end
```
こちらは、[Railsガイド](https://railsguides.jp/active_job_basics.html#%E3%83%90%E3%83%83%E3%82%AF%E3%82%A8%E3%83%B3%E3%83%89%E3%82%92%E8%A8%AD%E5%AE%9A%E3%81%99%E3%82%8B)に記載の手順に従っています。Railsガイドの同部分の記述によると、

> Active Jobには、Sidekiq、Resque、Delayed Jobなどさまざまなキューイングバックエンドに接続できるアダプタがビルトインで用意されています。

とのことなので、Rails側で公式的に`Sidekiq`との接続をサポートしているので、上記のような短い記述で接続の設定ができるのかしらと理解しました。

## さまざまな使い方
導入は以上のようにシンプルなのですが、では、一体何にどう使えば良いのでしょうか？

[公式のwiki](https://github.com/mperham/sidekiq/wiki)にはさまざまな記述がありますが、今回は、取り組んでいるRails課題の使い方に沿って[redisを使ってjobとオプションのデータを保存する方法](https://github.com/mperham/sidekiq/wiki/Using-Redis)について取り組んでいこうと思います。

### Redisにジョブを保存する

まず、`config/initializers/sidekiq.rb`を作成し、以下のように記載します。

```ruby:config/initializers/sidekiq.rb
Sidekiq.configure_server do |config|
  config.redis = { url: 'redis://localhost:6379' }
end

Sidekiq.configure_client do |config|
  config.redis = { url: 'redis://localhost:6379' }
end
```
ポイントは、Redisの場所を特定するのに`Sidekiq.configure_server`ブロックと`Sidekiq.configure_client`ブロックの両方を定義することです。

また、sidekiqはデフォルトで`localhost:6379`にアクセスしてRedisに接続しようとしますが、本番環境ではこれはうまくいかないので、[別の設定をしてねということが公式サイト該当ページのトップに](https://github.com/mperham/sidekiq/wiki/Using-Redis)書いてありました。

### オプションを設定する

また、今回は下記のオプションを設定しました。

```ruby:config/sidekiq.yml
:concurrency: 25
:queues:
  - default
  - mailers
```
なぜこのような形式になるのかは、[このQiita記事](https://qiita.com/ts-3156/items/a5f8794a79148c9cfcbe)で丁寧に解説されていました。

ポイントは、

- sidekiqのオプションはyml形式で指定し
- デフォルトでは`config/sidekiq.yml`ないにに設置する

そして、今回は**`concurrency`（並行性：同時処理できる件数(?)）**を25、**`queues:`（キューの実行順）**を、default, mailers の順に実施しています。

## 起動
ここで、一度起動させてみます。`config`以下に書いた設定コマンドを、以下のコマンドを実行します（参考：[Railsで非同期処理を行える「Sidekiq」](https://qiita.com/yumiyon/items/6835d90e621e73268021#%E8%B5%B7%E5%8B%95%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89))

```sh:
$ bundle exec sidekiq -C config/sidekiq.yml
```
無事、起動しました！
[![Image from Gyazo](https://i.gyazo.com/ed325fbf9d157f8b622ac7d51c74f9c0.png)](https://gyazo.com/ed325fbf9d157f8b622ac7d51c74f9c0)

### 確認画面で見る
`sidekiq`の稼働状況を画面で確認するために、`routes.rb`に以下のように記載します。

```ruby:config/routes.rb
require 'sidekiq/web'

Rails.application.routes.draw do

  if Rails.env.development?
    mount Sidekiq::Web, at: '/sidekiq'
  end
end
```

これで、`/sidekiq`にアクセスすることで確認画面が見られるようになりました！
[![Image from Gyazo](https://i.gyazo.com/55f662d4a047da44ec3f6039e650ebd8.png)](https://gyazo.com/55f662d4a047da44ec3f6039e650ebd8)

今回は、メール通知が送信されるアクションを`sidekiq`管理下においたのですが、メール送信の結果、きちんとダッシュボードに反応が示されています＾＾

## 完了＆感想

以上で実装は終わりです。非常に簡単でしたが、

- まだまだ非同期処理を実行しなければならない規模のアプリを作ったことがない
- メインである（？）[ジョブを作る](https://github.com/mperham/sidekiq/wiki/Getting-Started#rails)動作についてまだ何もやれていない

ので、実務で使うにはもう少し学習が必要そうです。
ですが、バックエンドの深いところに入ってきたかな？という感じがあるので、引き続き学習を深めていきたいと思います。