Railsサーバ起動の裏側

 Railsサーバ起動の裏側

ヒカラボさんのイベントで発表したスライドです

6ac7c50770603b53964d44db373e8e48?s=128

Shinichi Maeshima

February 27, 2018
Tweet

Transcript

  1. Railsサーバ起動の 裏側 前島 真一(@willnet)

  2. Shinichi Maeshima ! " # @netwillnet @willnet http://blog.willnet.in Organizer Rails

    Consultant
  3. 具体的には何してる人 なの • 技術やシステム設計に関する質問に答える • コードレビュー • 社内勉強会の開催 • ペアプロ

    • などなど(採用の相談とか技術以外のことも時々やって る)
  4. つまり • Railsの知見を会社に提供するおしごと

  5. 知見のうちの一つを お話します

  6. みんな大好き Ruby on Rails • Railsのお作法(レール)に乗ってるだけで、意識せずにべ んり技術を使えていて最高 • 例えばセキュリティ的には •

    HTMLの自動エスケープ • CSRFチェック用のトークンを自動で追加 • レスポンスヘッダに自動でセキュアになるやつを追加
  7. しかし • 魔法のようなプロダクトであるけれど、何も考えずブラッ クボックスとして扱っているとある日死ぬ • 何も考えずに <%= @post.body.html_safe %> などとす

    ると… •
  8. 裏側を理解する事が 大事

  9. ./bin/rails s の裏側

  10. bin/rails #!/usr/bin/env ruby begin load File.expand_path('../spring', __FILE__) rescue LoadError =>

    e raise unless e.message.include?('spring') end APP_PATH = File.expand_path('../config/application', __dir__) require_relative '../config/boot' require 'rails/commands'
  11. config/boot.rb ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__) require 'bundler/setup' # Set up

    gems listed in the Gemfile.
  12. bundler/setup • Gemfileに書かれているgemへのLOAD_PATHを追加する • この後からgemのrequireができるようになる

  13. railties/lib/rails/ commands.rb require "rails/command" aliases = { "g" => "generate",

    "d" => "destroy", "c" => "console", "s" => "server", "db" => "dbconsole", "r" => "runner", "t" => "test" } command = ARGV.shift command = aliases[command] || command Rails::Command.invoke command, ARGV
  14. lib/rails/commands/ server/server_command.rb def perform set_application_directory! Rails::Server.new(server_options).tap do |server| require APP_PATH

    Dir.chdir(Rails.application.root) server.start end end
  15. APP_PATHはbin/railsで 定義してた #!/usr/bin/env ruby begin load File.expand_path('../spring', __FILE__) rescue LoadError

    => e raise unless e.message.include?('spring') end APP_PATH = File.expand_path('../config/application', __dir__) require_relative '../config/boot' require 'rails/commands'
  16. config/applicaiton.rb require_relative 'boot' require 'rails/all' Bundler.require(*Rails.groups) module Hikalab class Application

    < Rails::Application config.load_defaults 5.1 end end
  17. railties/lib/rails/ all.rb require "rails" %w( active_record/railtie active_storage/engine action_controller/railtie action_view/railtie action_mailer/railtie

    active_job/railtie action_cable/engine rails/test_unit/railtie sprockets/railtie ).each do |railtie| begin require railtie rescue LoadError end end
  18. railties/lib/rails.rb module Rails class << self @application = @app_class =

    nil attr_writer :application def application @application ||= (app_class.instance if app_class) end # The Configuration instance used to configure the Rails environment def configuration application.config end def root application && application.config.root end def env @_env ||= ActiveSupport::StringInquirer.new( ENV["RAILS_ENV"].presence || ENV["RACK_ENV"].presence || “development" ) end end end
  19. activerecord/lib/ active_record/railtie.rb module ActiveRecord class Railtie < Rails::Railtie initializer "active_record.initialize_timezone"

    do ActiveSupport.on_load(:active_record) do self.time_zone_aware_attributes = true self.default_timezone = :utc end end initializer "active_record.logger" do ActiveSupport.on_load(:active_record) { self.logger ||= ::Rails.logger } end initializer "active_record.check_schema_cache_dump" do # ... end end end
  20. initializer do…end • Railsの初期設定を登録してあとで遅延実行するためのし くみ

  21. config/applicaiton.rb require_relative 'boot' require 'rails/all' Bundler.require(*Rails.groups) module Hikalab class Application

    < Rails::Application config.load_defaults 5.1 end end
  22. Bundler.require • Gemfileに書かれたgemをrequireする

  23. サーバが立ち上がるとどうなるか • Rack::Serverは慣習的にconfig.ruという設定ファイルを 読んで立ち上がる

  24. config.ru require_relative 'config/environment' run Rails.application

  25. config/environment.rb require_relative 'application' Rails.application.initialize!

  26. Rails.application.initialize! • ↑みたいなやつを実行する • config/initializers/*.rb を実行する initializer "active_record.initialize_timezone" do ActiveSupport.on_load(:active_record)

    do self.time_zone_aware_attributes = true self.default_timezone = :utc end end
  27. 時間足りないので 一旦ここまで

  28. Railsのブートのまとめ • Gemfileのgemをrequireできるようにする • Railsの設定に必要なものだけ先にロードする(ただし評 価は後) • Gemfileのgemをrequireする • 初期化処理をする

  29. これを知っていると どういうときに 嬉しいか

  30. ハマリポイントを 回避できる(ことがある) • gemの読み込み順番に起因するエラー • 設定の読み込み順番に起因するエラー • Rackミドルウェアの順番に起因する(ry

  31. 読み込み順に関連した事例 http://y-yagi.tumblr.com/post/150899354290/rails

  32. まとめ

  33. この機能べんり! だけではなくて

  34. 裏側を理解する事が 大事

  35. お互い頑張りましょう