mirror of
https://github.com/puma/puma.git
synced 2022-11-09 13:48:40 -05:00
Document Puma::Reactor#run_internal
This commit is contained in:
parent
8dbc6eb6ed
commit
5b2d3bd1ea
1 changed files with 47 additions and 0 deletions
|
@ -11,6 +11,8 @@ module Puma
|
|||
@app_pool = app_pool
|
||||
|
||||
@mutex = Mutex.new
|
||||
|
||||
# Read / Write pipes to wake up internal while loop
|
||||
@ready, @trigger = Puma::Util.pipe
|
||||
@input = []
|
||||
@sleep_for = DefaultSleepFor
|
||||
|
@ -21,6 +23,51 @@ module Puma
|
|||
|
||||
private
|
||||
|
||||
|
||||
# Until a request is added via the `add` method this method will internally
|
||||
# loop, waiting on the `sockets` array objects. The only object in this
|
||||
# array at first is the `@ready` IO object, which is the read end of a pipe
|
||||
# connected to `@trigger`. When `@trigger` is written to, then the loop
|
||||
# will break on IO.select and return an array.
|
||||
#
|
||||
# ## When a request is added:
|
||||
#
|
||||
# When the `add` method is called, an instance of `Puma::Client` is added to the `@input` array.
|
||||
# Next the `@ready` pipe is "woken" by writing a string of `"*"` to `@trigger`.
|
||||
#
|
||||
# When that happens the internal while loop stops blocking and returns a reference
|
||||
# to whatever "woke" it up. On the very first loop the only thing in `sockets` is `@ready`.
|
||||
# When `@trigger` is written to the loop "wakes" and the `ready`
|
||||
# variable returns an array of arrays like `[[#<IO:fd 10>], [], []]` where the
|
||||
# first IO object is the `@ready` object. This first array `[#<IO:fd 10>]`
|
||||
# is saved as a `reads` array.
|
||||
#
|
||||
# The `reads` array is iterated through and read. In the case that the object
|
||||
# is the same as the `@ready` input pipe, then we know that there was a `trigger` event.
|
||||
#
|
||||
#
|
||||
# If there was a trigger event then one byte of `@ready` is read into memory. In this case of the first request
|
||||
# it sees that it's a `"*"` and it adds the contents of `@input` into the `sockets` array.
|
||||
# The while loop continues to iterate again, but now the `sockets` array contains a `Puma::Client` instance in addition
|
||||
# to the `@ready` IO object. For example: `[#<IO:fd 10>, #<Puma::Client:0x3fdc1103bee8 @ready=false>]`.
|
||||
#
|
||||
# Since the `Puma::Client` in this example has data that has not been read yet,
|
||||
# the IO.select is immediately able to "wake" and read from the `Puma::Client`. At this point the
|
||||
# `ready` output looks like this: `[[#<Puma::Client:0x3fdc1103bee8 @ready=false>], [], []]`.
|
||||
#
|
||||
# Each element in the first entry is iterated over. The `Puma::Client` object is not
|
||||
# the `@ready` pipe so we check to see if we have the body, or only the header via
|
||||
# the `Puma::Client#try_to_finish` method. If the full request has been sent,
|
||||
# then it is passed off to the `@app_pool` thread pool so that a "worker thread"
|
||||
# can pick up the request and begin to run application logic. This is done
|
||||
# via `@app_pool << c`. The `Puma::Client` is then removed from the `sockets` array.
|
||||
#
|
||||
# If the request body is not present then nothing will happen, and the loop will iterate
|
||||
# again. When the client sends more data to the socket the `Puma::Client` object will
|
||||
# wake up the `IO.select` and it can again be checked to see if it's ready to be
|
||||
# passed to the thread pool.
|
||||
#
|
||||
# There is some timeout logic as well
|
||||
def run_internal
|
||||
sockets = @sockets
|
||||
|
||||
|
|
Loading…
Reference in a new issue