11# Learn-Rails-by-Reading-Source-Code
2+ [ ![ LICENSE] ( https://img.shields.io/badge/license-Anti%20996-blue.svg )] ( https://github.com/996icu/996.ICU/blob/master/LICENSE )
3+ [ ![ 996.icu] ( https://img.shields.io/badge/link-996.icu-red.svg )] ( https://996.icu )
24## Table of Contents
35
46 * [ Part 0: Before reading Rails 5 source code] ( #part-0-before-reading-rails-5-source-code )
2224
2325
2426## Part 0: Before reading Rails 5 source code
25- 1 ) I suggest you learn Rack [ http://rack.github.io/ ] ( http://rack.github.io/ ) first.
27+ 1 ) I suggest you to learn Rack [ http://rack.github.io/ ] ( http://rack.github.io/ ) first.
2628
27- In rack , an object with ` call ` method is a rack app.
29+ In Rack , an object with ` call ` method is a Rack app.
2830
2931So what is the object with ` call ` method in Rails? I will answer this question in Part 1.
3032
@@ -37,7 +39,7 @@ So what is the object with `call` method in Rails? I will answer this question i
3739
3840* How does Rails combine ActionController, ActionView and Routes together?
3941
40- * How does puma, rack , Rails work together?
42+ * How does Puma, Rack , Rails work together?
4143
4244* What's Puma's multiple threads?
4345
@@ -55,7 +57,7 @@ module Rails
5557 def perform
5658 # ...
5759 Rails ::Server .new (server_options).tap do |server |
58- # APP_PATH is '/Users/your_name /your_project/config/application'.
60+ # APP_PATH is '/path/to /your_project/config/application'.
5961 # require APP_PATH will create the 'Rails.application' object.
6062 # Actually, 'Rails.application' is an instance of `YourProject::Application`.
6163 # Rack server will start 'Rails.application'.
@@ -84,9 +86,9 @@ module Rails
8486 end
8587end
8688```
87- A rack server need to start with an ` App ` object. The ` App ` object should have a ` call ` method.
89+ A Rack server need to start with an ` App ` object. The ` App ` object should have a ` call ` method.
8890
89- ` config.ru ` is the conventional entry file for rack app. So let's look at it.
91+ ` config.ru ` is the conventional entry file for Rack app. So let's look at it.
9092``` ruby
9193# ./config.ru
9294require_relative ' config/environment'
@@ -264,9 +266,9 @@ Rack server will start `Rails.application` in the end.
264266
265267` Rails.application ` is an important object in Rails.
266268
267- And you'll only have one ` Rails.application ` in one puma process.
269+ And you'll only have one ` Rails.application ` in one Puma process.
268270
269- Multiple threads in a puma process shares the ` Rails.application ` .
271+ Multiple threads in a Puma process shares the ` Rails.application ` .
270272
271273## Part 2: config
272274The first time we see the ` config ` is in ` ./config/application.rb ` .
382384```
383385
384386### Puma
385- When a request is made from client, puma will process the request in ` Puma::Server#process_client ` .
387+ When a request is made from client, Puma will process the request in ` Puma::Server#process_client ` .
386388
387- If you want to know how puma enter the method ` Puma::Server#process_client ` , please read part 4 or just search 'process_client' in this document.
389+ If you want to know how Puma enter the method ` Puma::Server#process_client ` , please read part 4 or just search 'process_client' in this document.
388390
389391``` ruby
390392# ./gems/puma-3.12.0/lib/puma/server.rb
@@ -447,7 +449,7 @@ module Puma
447449
448450 # Given the request +env+ from +client+ and a partial request body
449451 # in +body+, finish reading the body if there is one and invoke
450- # the rack app. Then construct the response and write it back to
452+ # the Rack app. Then construct the response and write it back to
451453 # +client+
452454 #
453455 def handle_request (req , lines )
@@ -550,7 +552,7 @@ module Rails
550552 puts " caller: #{ caller .inspect} "
551553
552554 # You may want to know when is the @app first time initialized.
553- # It is initialized when 'config.ru' is load by rack server.
555+ # It is initialized when 'config.ru' is load by Rack server.
554556 # Please search `Rack::Server#build_app_and_options_from_config` in this document for more information.
555557 # When `Rails.application.initialize!` (in ./config/environment.rb) executed, @app is initialized.
556558 @app || @app_build_lock .synchronize { # '@app_build_lock = Mutex.new', so multiple threads share one '@app'.
@@ -704,8 +706,8 @@ module ActionDispatch
704706 end
705707
706708 def build (app )
707- # klass is rack middleware like : Rack::TempfileReaper, Rack::ETag, Rack::ConditionalGet or Rack::Head, etc.
708- # It's typical rack app to use these middlewares.
709+ # klass is Rack middleware like : Rack::TempfileReaper, Rack::ETag, Rack::ConditionalGet or Rack::Head, etc.
710+ # It's typical Rack app to use these middlewares.
709711 # See https://github.com/rack/rack-contrib/blob/master/lib/rack/contrib for more information.
710712 klass.new (app, * args, & block)
711713 end
730732# >
731733# >
732734```
733- As we see in the Rack middleware stack, the last one is
735+ As we see in the Rack middleware stack, the last @ app is
734736
735737` @app=#<ActionDispatch::Routing::RouteSet:0x00007fa1e594cbe8> `
736738``` ruby
@@ -1486,7 +1488,7 @@ module ActionView
14861488end
14871489
14881490```
1489- After all rack apps called, user will get the response.
1491+ After all Rack apps called, user will get the response.
14901492
14911493## Part 4: What does ` $ rails server ` do?
14921494
@@ -1707,7 +1709,7 @@ module Rails
17071709 def perform
17081710 # ...
17091711 Rails ::Server .new (server_options).tap do |server |
1710- # APP_PATH is '/Users/your_name /your_project/config/application'.
1712+ # APP_PATH is '/path/to /your_project/config/application'.
17111713 # require APP_PATH will create the 'Rails.application' object.
17121714 # 'Rails.application' is 'YourProject::Application.new'.
17131715 # Rack server will start 'Rails.application'.
@@ -1863,7 +1865,7 @@ module Puma
18631865 # with configuration in `config/puma.rb` or `config/puma/<env>.rb`.
18641866 #
18651867 # It is responsible for either launching a cluster of Puma workers or a single
1866- # puma server.
1868+ # Puma server.
18671869 class Launcher
18681870 def initialize (conf , launcher_args = {})
18691871 @runner = nil
@@ -1984,7 +1986,7 @@ module Puma
19841986 # This part is important.
19851987 # Remember the block of ThreadPool.new will be called when a request added to the ThreadPool instance.
19861988 # And the block will process the request by calling method `process_client`.
1987- # Let's step into this line later to see how puma call the block.
1989+ # Let's step into this line later to see how Puma call the block.
19881990 @thread_pool = ThreadPool .new (@min_threads ,
19891991 @max_threads ,
19901992 IOBuffer ) do |client , buffer |
@@ -2000,7 +2002,7 @@ module Puma
20002002
20012003 # ...
20022004 if process_now
2003- # Process the request. You can treat `client` as request.
2005+ # Process the request. You can look upon `client` as request.
20042006 # If you want to know more about 'process_client', please read part 3
20052007 # or search 'process_client' in this document.
20062008 process_client(client, buffer)
@@ -2014,7 +2016,7 @@ module Puma
20142016
20152017 if background # background: true (for this example)
20162018 # This part is important.
2017- # Remember puma created a thread here!
2019+ # Remember Puma created a thread here!
20182020 # We will know that the newly created thread's job is waiting for requests.
20192021 # When a request comes, the thread will transfer the request processing work to a thread in ThreadPool.
20202022 # The method `handle_servers` in thread's block will be executed immediately
@@ -2047,7 +2049,7 @@ module Puma
20472049 break if handle_check
20482050 else
20492051 if io = sock.accept_nonblock
2050- # You can simply think a Puma::Client instance as a request.
2052+ # You can simply look upon a Puma::Client instance as a request.
20512053 client = Client .new (io, @binder .env(sock))
20522054
20532055 # ...
@@ -2083,7 +2085,7 @@ module Puma
20832085 def initialize (min , max , * extra , & block )
20842086 # ..
20852087 @mutex = Mutex .new
2086- @todo = [] # @todo is requests (in puma , they are Puma::Client instances) which need to be processed.
2088+ @todo = [] # @todo is requests (in Puma , they are Puma::Client instances) which need to be processed.
20872089 @spawned = 0 # the count of @spawned threads
20882090 @min = Integer (min) # @min threads count
20892091 @max = Integer (max) # @max threads count
@@ -2149,7 +2151,7 @@ module Puma
21492151 @waiting -= 1
21502152 end
21512153
2152- # `work` is the request (in puma , it's Puma::Client instance) which need to be processed.
2154+ # `work` is the request (in Puma , it's Puma::Client instance) which need to be processed.
21532155 work = todo.shift if continue
21542156 end
21552157
@@ -2207,7 +2209,7 @@ module Puma
22072209 end
22082210
22092211 # work: #<Puma::Client:0x00007ff114ece6b0>
2210- # You can treat Puma::Client instance as a request.
2212+ # You can look upon Puma::Client instance as a request.
22112213 @todo << work
22122214
22132215 if @waiting < @todo .size and @spawned < @max
@@ -2241,9 +2243,9 @@ In `.run`, Puma will new a always running Thread for `ios = IO.select(#<TCPServe
22412243
22422244Request is created from ` ios ` object.
22432245
2244- A thread in puma threadPool will process the request.
2246+ A thread in Puma threadPool will process the request.
22452247
2246- The thread will invoke rack apps' ` call ` to get the response for the request.
2248+ The thread will invoke Rack apps' ` call ` to get the response for the request.
22472249
22482250### Exiting Puma
22492251#### Process and Thread
@@ -2311,7 +2313,7 @@ puts "Exit main thread"
23112313` ` `
23122314
23132315# ### Send `SIGTERM` to Puma
2314- When you stop puma by running ` $ kill -s SIGTERM puma_process_id` , you will enter ` setup_signals` in ` Puma::Launcher#run` .
2316+ When you stop Puma by running ` $ kill -s SIGTERM puma_process_id` , you will enter ` setup_signals` in ` Puma::Launcher#run` .
23152317` ` ` ruby
23162318# .gems/puma-3.12.0/lib/puma/launcher.rb
23172319module Puma
@@ -2453,14 +2455,14 @@ module Puma
24532455
24542456 # The created @thread is the @thread in ` stop` method below.
24552457 @thread = Thread.new {
2456- # FYI, this is in the puma starting process.
2458+ # FYI, this is in the Puma starting process.
24572459 # 'Thread.current.object_id' returns '70144220123860',
24582460 # which is the same as the 'Thread.current.object_id' in 'handle_servers' in Puma::Server#run
24592461 # def handle_servers
24602462 # begin
24612463 # # ...
24622464 # ensure
2463- # # FYI, the 'ensure' part is in the puma stopping process.
2465+ # # FYI, the 'ensure' part is in the Puma stopping process.
24642466 # puts "#{ Thread .current.object_id} " # returns '70144220123860' too.
24652467 # end
24662468 # end
@@ -2533,11 +2535,11 @@ module Puma
25332535
25342536 # ...
25352537 ensure
2536- # FYI, the 'ensure' part is in the puma stopping process.
2538+ # FYI, the 'ensure' part is in the Puma stopping process.
25372539 # 'Thread.current.object_id' returns '70144220123860',
25382540 # which is the same as the 'Thread.current.object_id' in 'Thread.new block' in Puma::Server#run
25392541 # @thread = Thread.new do
2540- # # FYI, this is in the puma starting process.
2542+ # # FYI, this is in the Puma starting process.
25412543 # puts "#{Thread.current.object_id}" # returns '70144220123860'
25422544 # handle_servers
25432545 # end
@@ -2611,7 +2613,7 @@ module Puma
26112613 # ..
26122614 @mutex = Mutex .new
26132615 @spawned = 0 # The count of @spawned threads.
2614- @todo = [] # @todo is requests (in puma , it's Puma::Client instance) which need to be processed.
2616+ @todo = [] # @todo is requests (in Puma , it's Puma::Client instance) which need to be processed.
26152617 @min = Integer (min) # @min threads count
26162618 @block = block # block will be called in method `spawn_thread` to process a request.
26172619 @workers = []
0 commit comments