Sidekiqのソース読んでみたメモ

sidekiqのソースを読んでみた

- [sidekiq](https://github.com/mperham/sidekiq)を使ってるけどなかってどうなってるの?というのを調べることがあったのでまとめ

# 前提
- バージョン
  - v5.2.5
- 読んでみたタイミング
  - 2019/03
- ここで書かないこと
  - siekiqの使い方
  - Thread周り
- 基本的なとこだけ読んでます
- 読んでみたなので正確ではないこともあります。。

# クライアント側(jobを積むほう)
## [Sidekiq::Worker](https://github.com/mperham/sidekiq/blob/v5.2.5/lib/sidekiq/worker.rb)
- 実行する処理とかを用意するクラスにincludeするモジュール
- includeしたクラスにperform_asyncとかが特異メソッドとして追加される

### #perform_async
- 中でSidekiq::Clientのオブジェクトを生成してpushを読んでる

## [Sidekiq::Client](https://github.com/mperham/sidekiq/blob/v5.2.5/lib/sidekiq/client.rb)
- redisにjobをつむところの役割をやってる

### #push
- workerに渡す引数＋jobのidを用意して整形してatomic_pushに投げる

### #atomic_push
- redisのqueuesていうキーにつむjobのキュー名を入れている(タイプがsetなので同じものを入れるときは重複しない)
- redisのqueue:キュー名のキーにjobを追加する

# サーバー側
- jobを実行するほう

## 登場するクラス
- [Sidekiq::CLI](https://github.com/mperham/sidekiq/blob/v5.2.5/lib/sidekiq/cli.rb)
  - サーバー側の起動を行う
  - そのあとは停止などのコマンドを受け付ける
- [Sidekiq::Launcher](https://github.com/mperham/sidekiq/blob/v5.2.5/lib/sidekiq/launcher.rb)
  - このオブジェクトのrunを呼べばサーバー側が動く
  - jobを取ってきて処理するのと、retryやスケジュールからqueueを積む処理を起動してくれるのでランチャー
- [Sidekiq::Manager](https://github.com/mperham/sidekiq/blob/v5.2.5/lib/sidekiq/manager.rb)
  - Sidekiq::Processorを作成＆ぐるぐる実行させる
- [Sidekiq::Processor](https://github.com/mperham/sidekiq/blob/v5.2.5/lib/sidekiq/processor.rb)
  - 一定時間ごとにqueueをチェックしに行って処理を実行
  - こいつがperformを呼び出してる
- [Scheduled::Poller](https://github.com/mperham/sidekiq/blob/v5.2.5/lib/sidekiq/scheduled.rb)
  - 即時実行じゃないjobや一度失敗したjpbを確認して、実行タイミングになったらqueueに積む

## sidekiq起動のところ
### [bin/sidekiq](https://github.com/mperham/sidekiq/blob/v5.2.5/bin/sidekiq)
- Sidekiq::CLI.instance
  - Sidekiq::CLIのインスタンスを生成(instanceってなんだ?と思ったけどシングルトンだった。。)
- Sidekiq::CLI#parse
  -  設定とかをsetしてる
- Sidekiq::CLI#run
  -  Sidekiq::Launcherのインスタンスを生成&Sidekiq::Launcher#runを呼び出したあとはコマンドを受け付けるためぐるぐるし続ける。
  - Sidekiq::Launcher#run
    -  Sidekiq::Manager#startとSidekiq::Scheduled::Poller#startを呼び出す
      - Sidekiq::Manager#start
        - Sidekiq::Processor#startを呼び出す
          - Sidekiq::Processor#start
            - スレッドでrunを実行
              - Sidekiq::Processor#run
                - jobがあればとってきて該当workerのperformを実行をぐるぐる。
      - Sidekiq::Scheduled::Poller#start
        - redisのretryとscheduleの中で実行タイミングになったものを取り出してqueueにつむ。
          - retryとscheduleはzsetで、timestampをキーにしてて、今の時間よりも小さいものーでとってるっぽい

ざっくりかくと
Sidekiq::CLI -> Sidekiq::Launcherを叩いてあとは入力待ちぐるぐる
Sidekiq::Launcher#run -> Sidekiq::Manager#startとSidekiq::Scheduled::Poller#startを叩く
Sidekiq::Manager#start -> Sidekiq::Processorをぐるぐるさせる
Sidekiq::Scheduled::Poller -> ぐるぐる

# おまけでRedisに登録されるもの
※ namespaceは省く

|キー  | type  | 値 |
|---|---|---|----|
|schedule | zset | 予定されたジョブが入っている | 
| queues | set | 一度でもジョブが積まれたキューのリスト |
| stat:processed | string | 完了したジョブの数 |
| stat:processed:yyyy-mm-dd | string | 該当日に完了したジョブの数 |
| stat:failed | string | 失敗したジョブの数 |
| stat:failed:yyyy-mm-dd | string | 該当日に失敗したジョブの数 |
| queue:キュー名 | list | そのキューの待機状態のジョブのリスト |
| limit:processes | set | TODO (limit:heartbeatのUUIDが入っていた。。) |
| limit: heartbeat:UUID | string | TODO (trueとか入ってる。。) |
| host:port:xxxx:workers | hash | そのworkerが現在実行中のジョブの情報 |



# 感想
- ランチャーってなんぞと思ったけど、一括で必要なのを起動してくれるもののことらしいと今回知った。。
- Threadとか詳しくないのでいつかちゃんと触って理解しよう。。
- redisの型とか全然知らなかったのでちょっと知れてよかった。
- gemを読んでみたって記事はありなのか。。？(お勉強メモなのでお許しください。。)
- 顔文字とか絵文字のメソッドがちょいちょいあって面白かった