Date | Commit message (Collapse) |
|
Since EventMachine 1.0.0 in 2012, the EM.defers_finish? API
exists to check for the existence of deferred actions.
Support it if it exists in the running version of EM and
update the note in our SIGNALS document.
Thanks to <alex0375@gmail.com> on the mailing list for bringing
this up:
https://bogomips.org/rainbows-public/CAKwvcL-VH3we4qA1pkNAstTmWvqNA=Rir2N_YiWztV_qbaLQvA@mail.gmail.com/
|
|
unicorn 4.8.x shutdown handling is different and no longer removes
items from the event loop. So we must do that ourselves to enable
graceful shutdown. Otherwise, we'll time out on shutdowns and
the master will forcibly kill us.
|
|
...rather than falling through worker_loop
Prior to the application of this patch, if an EventMachine
reactor_thread has already been started elsewhere before the
worker_loop is entered, the worker_loop exits as a second call
to EM.run does not block the current thread.
This patch causes the worker_loop thread to join the
reactor_thread if it is running.
[ew: commit message formatting]
Signed-off-by: Eric Wong <normalperson@yhbt.net>
|
|
Cramp has a homepage and mailing list now, yay!
|
|
Oops, testing against new changes against cramp.git here
|
|
This can allow Cramp (and potentially other libraries)
to subclass or implement duck-type compatible versions
of Rainbows::EventMachine::Client.
|
|
It should hopefully give this more visibility even though it's
an internal feature.
|
|
Since it's cheap to maintain keepalive clients with EM, we need
a way of disconnecting them in a timely fashion on rare SIGQUIT
events.
|
|
Hopefully makes things easier to try out.
|
|
ev_core is always loaded after forking, so eliminate the
need for extra setup steps for each concurrency model that
uses it
|
|
Code organization is hard :<
|
|
Rack::Utils::HeaderHash is still very expensive in Rack 1.2,
especially for simple things that we want to run as fast as
possible with minimal interference. HeaderHash is unnecessary
for most requests that do not send Content-Range in responses.
|
|
This should make things easier to find
|
|
One line of code saved! We'll also avoid loading
DeferredChunkResponse which is rarely needed
(unlike DeferredResponse).
|
|
The HttpParser#next? method will come with keepalive protection
for Rainbows!, which can prevent clients from monopolizing a
server with excessive pipelining/keepalive requests.
|
|
This is only needed for concurrency options that
do not use TeeInput, since TeeInput automatically
handles this for us.
|
|
These allow for small reductions in the amount of variables
we have to manage, more changes coming with later Unicorns.
|
|
This simplifies and disambiguates most constant resolution
issues as well as lowering our identation level. Hopefully
this makes code easier to understand.
|
|
It removes the burden of byte slicing and setting file
descriptor flags. In some cases, we can remove unnecessary
peeraddr calls, too.
|
|
Noise is bad.
|
|
Although this behavior is mentioned on the documentation,
this was broken under EventMachine, Rev*, and Revactor.
Furthermore, we set the "Connection: close" header to allow the
client to optimize is handling of non-keepalive connections.
|
|
Trying to avoid adding singleton methods since it's too easily
accessible by the public and not needed by the general public.
This also allows us (or just Zbatery) to more easily add support
systems without FD_CLOEXEC or fcntl, and also to optimize
away a fcntl call for systems that inherit FD_CLOEXEC.
|
|
EventMachine may close the underlying file descriptor on us if
there are unrecoverable errors during write. So IO#closed? is
a pointless check because EM does not invalidate the underlying
file descriptor.
|
|
Since TCP sockets stream, HTTP requests do not come in at
well-defined boundaries and it's possible for pipelined requests
to come in in a staggered form. We need to ensure our
receive_data callback doesn't fire any actions at all while
responding with a deferrable @body.
We still need to be careful about buffering, since EM does not
appear to allow temporarily disabling read events (without
pausing writes), so we shutdown the read end of the socket
if it reaches a maximum header size limit.
|
|
Not sure where this is happening, but this can trigger
Errno::EBADF under heavy load.
|
|
EM::FileStreamer writes may be intermingled with the headers
in the subsequent response if we enable processing of the
second pipelined response right away, so wait until the
first response is complete before hitting the second one.
This also avoids potential deep stack recursion in the unlikely
case where too many requests are pipelined.
|
|
This is cheaper for serving static files and only
slightly more expensive for pipes and sockets (extra
path lookup for File.stat).
|
|
We need to remember to close response bodies even if
a client aborts the connection, since body.close can
trigger interesting things like logging and such...
|
|
EM::FileStreamer must be passed a path, so should release
our newly opened descriptor first :<
|
|
Middlewares like Clogger may wrap Rack::File responses
with another body that responds to to_path and still
rely on #close to trigger an action (writing out the log
file).
|
|
Some middlewares such as Clogger rely on wrapping the body
having the close method called on it for logging.
|
|
We also properly fail on EM::FileStreamer responses, too
|
|
Extraneous returns are harder to follow.
|
|
Some applications may not use Response*Pipe and TryDefer at all,
so there's no reason to pollute the runtime with extra nodes to
mark during GC.
|
|
This makes it easier to write proxies for slow clients that
benefit from keep-alive. We also need to be careful about
non-HTTP/1.1 connections that can't do keepalive, now.
|
|
If a response proxying a pipe (or socket) includes a
Content-Length, do not attempt to outsmart the application
and just use the given Content-Length.
This helps avoid exposing applications to weird internals such
as env["rainbows.autochunk"] and X-Rainbows-* response headers.
|
|
No need to double up on begin blocks since we know @client.write
won't raise exceptions @io.read_nonblock does. Also prefer
@client.write to @client.send_data since it looks more in
line with other IO interfaces.
|
|
Since the EM loop runs entirely in one thread, we can get away
with using a single buffer across all pipe/socket responses.
|
|
Using EM.enable_proxy with EM.attach seems to cause
EM::Connection#receive_data callbacks to be fired before the
proxy has a chance to act, leading the first few chunks of data
being lost in the default receive_data handler. Instead
just rely on EM.watch like the chunked pipe.
|
|
Rack::File already sets the Content-Length header for us,
so there's no reason to ever set this ourselves.
|
|
This will give each concurrency model more control over
particular code paths and serving static files.
|
|
Since we suck at building websites, we just rely on RDoc as a
website builder. And since Rainbows! is an application server
(and not a programming library), our internal API should be of
little interest to end users.
Anybody interested in Rainbows! (or any other project) internals
should be reading the source.
|
|
For consistency with rev_write_response (and the existing
"write_response").
|
|
Cramp monkey patches Rainbows internals for WebSockets
support and we forgot about it. Add a new integration
test to ensure this continues to work in the future
(and force us to update the test for newer Cramp).
|
|
This hopefully allows the "sendfile" gem to be required
anywhere in the Rainbows!/Unicorn config file, and not
have to be required via RUBYOPT or the '-r' command-line
switch.
We also modularize HttpResponse and avoids singleton methods
in the response path. This (hopefully) makes it easier for
individual concurrency models to share code and override
individual methods.
|
|
HeaderHash objects can only be used as headers without
violating Rack::Lint in Rack 1.1.0 or later.
|
|
Array#[] lookups are slightly faster under both rbx and 1.9,
and easier to read.
|
|
Since EventMachine and Rev shared the same logic for optimizing
and avoiding extra file opens for IO/File-ish response bodies,
so centralize that.
For Ruby 1.9 users, we've also enabled this logic so ThreadPool,
ThreadSpawn, WriterThreadPool, and WriterThreadSpawn can take
advantage of Rainbows::DevFdResponse-generated bodies while
proxying sockets.
|
|
Since deferred requests run in a separate thread, this affects
the root (non-deferred) thread as well since it may share
data with other threads.
|
|
Merb (and possibly other) frameworks that support conditionally
deferred app dispatch can now use it just like Ebb and Thin.
http://brainspl.at/articles/2008/04/18/deferred-requests-with-merb-ebb-and-thin
|