mirror of
https://github.com/puma/puma.git
synced 2022-11-09 13:48:40 -05:00
Updates docs, removes refs. to IO.select()
[ci skip]
This commit is contained in:
parent
65df7f06b1
commit
81201a176e
2 changed files with 20 additions and 19 deletions
|
@ -27,9 +27,10 @@ module Puma
|
||||||
# For example a web request from a browser or from CURL. This
|
# For example a web request from a browser or from CURL. This
|
||||||
#
|
#
|
||||||
# An instance of `Puma::Client` can be used as if it were an IO object
|
# An instance of `Puma::Client` can be used as if it were an IO object
|
||||||
# for example it is passed into `IO.select` inside of the `Puma::Reactor`.
|
# by the reactor, that's because the latter is expected to call `#to_io`
|
||||||
# This is accomplished by the `to_io` method which gets called on any
|
# on any non-IO objects it polls. For example nio4r internally calls
|
||||||
# non-IO objects being used with the IO api such as `IO.select.
|
# `IO::try_convert` (which may call `#to_io`) when a new socket is
|
||||||
|
# registered.
|
||||||
#
|
#
|
||||||
# Instances of this class are responsible for knowing if
|
# Instances of this class are responsible for knowing if
|
||||||
# the header and body are fully buffered via the `try_to_finish` method.
|
# the header and body are fully buffered via the `try_to_finish` method.
|
||||||
|
|
|
@ -20,10 +20,11 @@ module Puma
|
||||||
#
|
#
|
||||||
# ## Reactor Flow
|
# ## Reactor Flow
|
||||||
#
|
#
|
||||||
# A request comes into a `Puma::Server` instance, it is then passed to a `Puma::Reactor` instance.
|
# A connection comes into a `Puma::Server` instance, it is then passed to a `Puma::Reactor` instance,
|
||||||
# The reactor stores the request in an array and calls `IO.select` on the array in a loop.
|
# which stores it in an array and waits for any of the connections to be ready for reading.
|
||||||
#
|
#
|
||||||
# When the request is written to by the client then the `IO.select` will "wake up" and
|
# The waiting/wake up is performed with nio4r, which will use the apropriate backend (libev, Java NIO or
|
||||||
|
# just plain IO#select). The call to `NIO::Selector#select` (hereinafter `select()`) will "wake up" and
|
||||||
# return the references to any objects that caused it to "wake". The reactor
|
# return the references to any objects that caused it to "wake". The reactor
|
||||||
# then loops through each of these request objects, and sees if they're complete. If they
|
# then loops through each of these request objects, and sees if they're complete. If they
|
||||||
# have a full header and body then the reactor passes the request to a thread pool.
|
# have a full header and body then the reactor passes the request to a thread pool.
|
||||||
|
@ -69,19 +70,18 @@ module Puma
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
|
||||||
# Until a request is added via the `add` method this method will internally
|
# 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
|
# 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
|
# array at first is the `@ready` IO object, which is the read end of a pipe
|
||||||
# connected to `@trigger` object. When `@trigger` is written to, then the loop
|
# connected to `@trigger` object. When `@trigger` is written to, then the loop
|
||||||
# will break on `IO.select` and return an array.
|
# will break on `select()` and return an array.
|
||||||
#
|
#
|
||||||
# ## When a request is added:
|
# ## When a request is added:
|
||||||
#
|
#
|
||||||
# When the `add` method is called, an instance of `Puma::Client` is added to the `@input` array.
|
# 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`.
|
# Next the `@ready` pipe is "woken" by writing a string of `"*"` to `@trigger`.
|
||||||
#
|
#
|
||||||
# When that happens, the internal loop stops blocking at `IO.select` and returns a reference
|
# When that happens, the internal loop stops blocking at `select()` and returns a reference
|
||||||
# to whatever "woke" it up. On the very first loop, the only thing in `sockets` is `@ready`.
|
# 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`
|
# When `@trigger` is written-to, the loop "wakes" and the `ready`
|
||||||
# variable returns an array of arrays that looks like `[[#<IO:fd 10>], [], []]` where the
|
# variable returns an array of arrays that looks like `[[#<IO:fd 10>], [], []]` where the
|
||||||
|
@ -97,7 +97,7 @@ module Puma
|
||||||
# to the `@ready` IO object. For example: `[#<IO:fd 10>, #<Puma::Client:0x3fdc1103bee8 @ready=false>]`.
|
# 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,
|
# 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
|
# the `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>], [], []]`.
|
# `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
|
# Each element in the first entry is iterated over. The `Puma::Client` object is not
|
||||||
|
@ -109,12 +109,12 @@ module Puma
|
||||||
#
|
#
|
||||||
# If the request body is not present then nothing will happen, and the loop will iterate
|
# 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
|
# 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
|
# wake up the `select()` and it can again be checked to see if it's ready to be
|
||||||
# passed to the thread pool.
|
# passed to the thread pool.
|
||||||
#
|
#
|
||||||
# ## Time Out Case
|
# ## Time Out Case
|
||||||
#
|
#
|
||||||
# In addition to being woken via a write to one of the sockets the `IO.select` will
|
# In addition to being woken via a write to one of the sockets the `select()` will
|
||||||
# periodically "time out" of the sleep. One of the functions of this is to check for
|
# periodically "time out" of the sleep. One of the functions of this is to check for
|
||||||
# any requests that have "timed out". At the end of the loop it's checked to see if
|
# any requests that have "timed out". At the end of the loop it's checked to see if
|
||||||
# the first element in the `@timeout` array has exceed its allowed time. If so,
|
# the first element in the `@timeout` array has exceed its allowed time. If so,
|
||||||
|
@ -124,7 +124,7 @@ module Puma
|
||||||
#
|
#
|
||||||
# This behavior loops until all the objects that have timed out have been removed.
|
# This behavior loops until all the objects that have timed out have been removed.
|
||||||
#
|
#
|
||||||
# Once all the timeouts have been processed, the next duration of the `IO.select` sleep
|
# Once all the timeouts have been processed, the next duration of the `select()` sleep
|
||||||
# will be set to be equal to the amount of time it will take for the next timeout to occur.
|
# will be set to be equal to the amount of time it will take for the next timeout to occur.
|
||||||
# This calculation happens in `calculate_sleep`.
|
# This calculation happens in `calculate_sleep`.
|
||||||
def run_internal
|
def run_internal
|
||||||
|
@ -320,7 +320,7 @@ module Puma
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# The `calculate_sleep` sets the value that the `IO.select` will
|
# The `calculate_sleep` sets the value that the `select()` will
|
||||||
# sleep for in the main reactor loop when no sockets are being written to.
|
# sleep for in the main reactor loop when no sockets are being written to.
|
||||||
#
|
#
|
||||||
# The values kept in `@timeouts` are sorted so that the first timeout
|
# The values kept in `@timeouts` are sorted so that the first timeout
|
||||||
|
@ -351,18 +351,18 @@ module Puma
|
||||||
# object.
|
# object.
|
||||||
#
|
#
|
||||||
# The main body of the reactor loop is in `run_internal` and it
|
# The main body of the reactor loop is in `run_internal` and it
|
||||||
# will sleep on `IO.select`. When a new connection is added to the
|
# will sleep on `select()`. When a new connection is added to the
|
||||||
# reactor it cannot be added directly to the `sockets` array, because
|
# reactor it cannot be added directly to the `sockets` array, because
|
||||||
# the `IO.select` will not be watching for it yet.
|
# the `select()` will not be watching for it yet.
|
||||||
#
|
#
|
||||||
# Instead what needs to happen is that `IO.select` needs to be woken up,
|
# Instead what needs to happen is that `select()` needs to be woken up,
|
||||||
# the contents of `@input` added to the `sockets` array, and then
|
# the contents of `@input` added to the `sockets` array, and then
|
||||||
# another call to `IO.select` needs to happen. Since the `Puma::Client`
|
# another call to `select()` needs to happen. Since the `Puma::Client`
|
||||||
# object can be read immediately, it does not block, but instead returns
|
# object can be read immediately, it does not block, but instead returns
|
||||||
# right away.
|
# right away.
|
||||||
#
|
#
|
||||||
# This behavior is accomplished by writing to `@trigger` which wakes up
|
# This behavior is accomplished by writing to `@trigger` which wakes up
|
||||||
# the `IO.select` and then there is logic to detect the value of `*`,
|
# the `select()` and then there is logic to detect the value of `*`,
|
||||||
# pull the contents from `@input` and add them to the sockets array.
|
# pull the contents from `@input` and add them to the sockets array.
|
||||||
#
|
#
|
||||||
# If the object passed in has a timeout value in `timeout_at` then
|
# If the object passed in has a timeout value in `timeout_at` then
|
||||||
|
|
Loading…
Reference in a new issue