Rails チュートリアル 1章 勉強メモ15
Rails チュートリアルの勉強メモ
- 前回までのあらすじ
- application_controller を読んでたら
protect_from_forgery
が気になって脱線してしまった
- application_controller を読んでたら
protect_from_forgery
- 前回眠すぎてよくわかんなかった origin ちょっとググってみた
これ見ると前回の
=> 127: before_action :verify_authenticity_token, options 128: append_after_action :verify_same_origin_request
が token 発行して同一の origin かどうか検証してるってことがなんとなくわかる。
hello world
class ApplicationController < ActionController::Base protect_from_forgery with: :exception def hello render html: "hello, world!" end end
- protect_from_forgery に釣られましたが無事なんとか終了
config/routes.rb
Rails.application.routes.draw do root 'application#hello' end
- ルートを application コントローラーの hello メソッドに設定している
- rails s でサーバーを立ち上げて、ブラウザなどで
http://localhost:3000
に入ると hello, world! と表示される
backtrace
- hello で backtrace をしてみて色々気になってきた
- Puma からみてみる
Puma::ThreadPool
puma-3.12.1/lib/puma/thread_pool.rb @ line 135 Puma::ThreadPool#spawn_thread: 130: if @clean_thread_locals 131: ThreadPool.clean_thread_locals 132: end 133: 134: begin => 135: block.call(work, *extra) 136: rescue Exception => e 137: STDERR.puts "Error reached top of thread-pool: #{e.message} (#{e.class})" 138: end 139: end 140:
- 一番深いメソッド
thread_pool.rb のコメントを読んでみる
Puma の worker は、 thread pool を持っている
- まず、クライアントへの接続は
Puma::Server
で行われる - それは
Puma::Client
にラップされ、Puma::Reactor
に渡される? - リクエストの準備が整うとPuma::ThreadPool#<<を介して、スレッドプールに渡され@todoに保存される
プール内の各スレッドは内部ループを持ち、@todo からリクエストをプルして進めていく
def spawn_thread をさらっとみてみる
- @spawned で立ち上っているスレッドの数がわかる
[1] pry(#<Puma::ThreadPool>)> @spawned => 5
- Thread.new でスレッドを作る
- Thread.list で立ち上がっているスレッドを確認できる
#<Thread:0x00007fd32c272fc0@puma 001@$HOME/.rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/puma-3.12.1/lib/puma/thread_pool.rb:89 sleep_forever>, #<Thread:0x00007fd32c272e80@puma 002@$HOME/mitsuki/.rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/puma-3.12.1/lib/puma/thread_pool.rb:89 sleep_forever>, #<Thread:0x00007fd32c272cf0@puma 003@$HOME.rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/puma-3.12.1/lib/puma/thread_pool.rb:89 run>, #<Thread:0x00007fd32c272b60@puma 004@$HOME/.rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/puma-3.12.1/lib/puma/thread_pool.rb:89 sleep_forever>, #<Thread:0x00007fd32c272a48@puma 005@$HOME/.rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/puma-3.12.1/lib/puma/thread_pool.rb:89 sleep_forever>,
- これら以外にもスレッドは立ち上がっていたが、puma のスレッドは5つ
mutex.synchronize do while todo.empty? if @trim_requested > 0 @trim_requested -= 1 continue = false not_full.signal break end if @shutdown continue = false break end @waiting += 1 not_full.signal not_empty.wait mutex @waiting -= 1 end work = todo.shift if continue end
- todo が空の場合
- mutex.synchronize は ブロックの中の処理の間はロックされる
- 削除要求が ある場合
- 削除要求を-1する
- continue を false に
- mutex.synchronize 抜けた後の処理を続けるかどうかのフラグ
- not_full.signal
- not_full, not_empty は状態変数
- not_full は スレッドが full の時に処理を止めるのかな?
- not_full.signal は not_full状態変数で待っているスレッドを再開させる
- スレッド終了するからmutex空くってことかな?
- シャットダウンのとき
- プールのすべてのスレッドを終了するのでそのまま終了
- todo が空で、削除要求もなし、シャットダウンでもない場合
- @waiting を +1
- スレッドがフルでないことを知らせる
- スレッドが空なので待機
- not_empty.signal がきたら @waiting を -1 して再開
work に todo の要素を取り出して継続
@clean_thread_locals が true の時
- Thread.current[key] = nil してる
block.call(work, *extra)
- block は puma-3.12.1/lib/puma/server.rb の run
- server の 実行をする
- SSLError, HttpParserError, ConnectionError, EOFError の時の処理をする
- 今回は通る、そして process_now は true なので
process_client client, buffer
- ここの client, buffer は block.call(work, *extra) での work, extra
puma-3.12.1/lib/puma/server.rb
- ここではクライアントへの接続を行なっている
- handle_request(client, buffer)
- リクエストを受け取る処理
puma-3.12.1/lib/puma/server.rb @ line 660 Puma::Server#handle_request
puma-3.12.1/lib/puma/configuration.rb @ line 227 Puma::Configuration::ConfigMiddleware#call
class ConfigMiddleware def initialize(config, app) @config = config @app = app end def call(env) env[Const::PUMA_CONFIG] = @config @app.call(env) end end
- Configuration オブジェクトに env を入れる
- app は rails の app
- ここでは hello_app
@app.call(env) でついに hello_app を呼び出す
backtrace で application_controller の hello までの道のり
- イマココ --> #58 Puma::Configuration::ConfigMiddleware.call(env#Hash) at $HOME/.rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/puma-3.12.1/lib/puma/configuration.rb:227
- 深すぎる