Age | Commit message (Collapse) | Author |
|
|
|
|
|
|
|
Lift the restriction that a listener must be suspended before
transport options can be changed.
* Changes to the `max_connections`, `handshake_timeout` and `shutdown`
options will take effect immediately.
* Changes to the `num_acceptors`, `num_listen_sockets` and `socket_opts`
options will take effect when a listener is suspended and resumed, or
when the acceptors supervisor restarts.
* Changes to the `num_conns_sups` and `connection_type` options will only
take effect when the connections super-supervisor restarts.
* Changes to the `logger` option will never take effect, unless a listener
is stopped and started with fresh transport options.
The fetching and handing down of transport options changes with this
commit, to ensure consistency between the individual components in the
hierarchy.
* The `num_acceptors` option is handed down from the listener supervisor to
the acceptors supervisor in the child spec, while the `num_listen_sockets`
and `socket_opts` options are read inside the acceptors supervisor itself.
This way, the `num_acceptors` option will only take effect when the listener
supervisor restarts, whereas the other two options will take effect
when acceptors supervisor restarts. This commit moves the fetching of
the `num_acceptors` option into the acceptors supervisor as well.
* The `logger` option is read in multiple places throughout the hierarchy.
This way it may happen that processes that suffered a crash and restart
may use a different logger than other processes that did not. This commit
reads the `logger` from the transport options given to the listener supervisor
start function, and hands it down from there.
* The `connection_type` option is read individually by each connection supervisor.
This way, a restart of an individual connection supervisor may cause them
to use a different connection type than the others. This commit reads the
transport options in the connections super-supervisor, and hands them down to
the individual connections supervisors.
* The `num_conns_sups` is handed down from the listener supervisor to the
connections super-supervisor. This way, a change to this option will only
take effect when the listener supervisor restarts. This commit moves
the fetching of this option inside the connections super-supervisor. This
change is merely for structural consistency, it is not necessary for operational
consistency.
|
|
|
|
It was working already but the types were wrong and some small
details needed to be corrected.
|
|
This new option allows configuring the number of connection
supervisors. The old behavior can be obtained by setting this
value to 1. A value larger than num_acceptors will result in
some connection supervisors not being used as the acceptors
currently only use one connection supervisor.
|
|
This gets rid of a bottleneck that occurs when many connections
are handled by a single supervisor. The bigger issue occurred
when many connections were dropped at once and the supervisor
couldn't keep up.
|
|
The race condition occurs when the restart is faster than
the cleaning up. With this commit the restart will perform
the cleanup if it was not done beforehand.
|
|
In addition to cleaning when ranch:stop_listener/1 is called, we
also need to clean when we detect the supervisor is going away
for normal reasons, because the supervisor might be in another
application's supervision tree.
Note that there might be a short delay in this case before the
cleanup is done, due to using monitors for detection.
|
|
|
|
This allows graceful draining of connections, updating transport
options on a running listener without having to drop connections
and other similar scenarios.
Note that when updating transport options the listener must be
suspended which means that new connections will be rejected until
the listener is resumed.
|
|
|
|
|
|
|
|
|
|
In some cases the ranch_server:get_connections_sup/1 call could
still succeed depending on timing.
|
|
|
|
|
|
|
|
|
|
All of it can be found in the manual, which defines what the
code must do, and is always up to date unlike the code comments.
|
|
|
|
A ranch_conns_sup could be (re)started and call
ranch_server:set_connections_sup/2 before ranch_server has handled the
predecessor's exit. This would cause the ranch_server to crash because
ets:insert_new/2 would return false.
This change allows ranch_server to handle this case by crashing the
calling process instead of itself.
|
|
When ranch_server crashes it will now remonitor previously registered
ranch_conns_sup processes so they can be removed from the registry when
they die.
|
|
We just don't need this process anymore. Less, simpler code!
API changes:
* Protocols start_link first argument is now Ref instead of ListenerPid
* ranch:accept_ack/1 argument is now Ref instead of ListenerPid
* ranch_listener:remove_connection/1 becomes ranch:remove_connection/1
and its argument is now Ref instead of ListenerPid
Ref is the name of the listener given as first argument to start_listener/6.
|
|
This change was designed so that we don't have this supervisor
and ranch_listener performing the same job, namely monitoring
connection processes, the first through links and the second
through monitors.
This change also makes possible various optimizations:
* Acceptors don't need to know about options, maximum number
of connections, or anything else. They can just accept,
pass the socket to the supervisor, and when the supervisor
replies continue accepting connections.
* The supervisor holds most of the information that will be
passed to created processes. This reduces copying.
* The supervisor temporarily takes ownership of the socket,
then creates the connection process and gives it ownership,
streamlining the creation.
* The supervisor can hold acceptors in their receive loop if
max_connections is reached. When this number gets below the
limit it can then send a message to a sleeping acceptor to
make it resume its operations.
* Because we know that all connection process creations are made
from the local Erlang node, we can greatly reduce the number
operations to be made when calling the supervisor.
* Because all acceptors die if this supervisor dies, we can
remove even more operations from the calling code. We do not
need to monitor or wait for a timeout. This reduces the call
code to two statements: send and receive. (Thanks James Fish
for helping with that.)
* The supervisor only needs to keep track of a list of pids.
There is no children specification to be maintained, we do
not need to handle restart strategy (no process can be
restarted because the socket dies with it). We are using
the process dictionary for storing the pids as it proved
to be the simplest and fastest solution.
* The supervisor maintains a count of current connections,
but also of processes (including the ones that removed
themselves from the pool), making any query of these values
very fast.
The supervisor should still be compatible with OTP principles.
It responds to calls from the supervisor module as expected,
although some of them are disabled and an error will be returned,
for example supervisor:start_child/2. It is also started with
proc_lib and handles system messages. sys:get_status/1 can thus
be used as expected.
We can see a great increase in the number of requests/s, a great
improvement in the latency of requests, and we can simply accept
requests faster than before. It will probably have a bigger increase
under virtualized environments, although that's only a guess.
As a result of this, we don't write much anymore in the ranch_server
ets table, so the write_concurrency option was removed. Tests were
also slightly improved to prevent race conditions.
|
|
There is no need to contact the server and track requests unless being
asked to do so by the user. It's going to be faster and more efficient
to not track anything when being told tracking doesn't matter.
Whenever the max connections is set to infinity, the connections
counting key is not created, or is deleted if it existed already.
When using a numeric value, the connection count is created or
maintained if it existed already.
Moreover, trying to reduce a listener's counter while the max connection
number is set to `infinity` will return 0 and avoid all counting
operations as they are meaningless.
|
|
|
|
Two general issues were addressed. The first one is the issue with
statically defined pids passed into childspecs. This issue prevents
regular supervisor' children restarts in the case of someone's
failure.
The second one is the not quite appropriate restart strategy.
Changed to rest_for_one which in pair with previous fixes assures
that live connections will not die in the case of partial failure.
Among possible failures are listening socket shutdown or frequent
accept errors.
|
|
Should prove itself more robust when things go wrong.
|
|
Ranch now accepts connection asynchronously through a separate
process. The accept process is linked to the acceptor, calls
accept and does nothing else but send the socket back to the
acceptor. This allows us to receive messages in the acceptor
to handle upgrades instead of polling. This will also allow us
later to make acceptors system processes.
Remove support for connection pools in favor of a simpler
max_connections setting. Connections can be removed from the
count, allowing us to have as many long-lived connections as
we want while still limiting the number of short-lived ones.
Add max_connections, max_connections with long-lived connections,
and upgrade tests.
|
|
This way, if a crash happens in one of them after a protocol options
upgrade has occured, the restarted acceptor will get the upgraded
options as expected, and not the initial ones.
|
|
|
|
|