I don't have an rpm machine handy anymore. I suspect this should
always have been filled in by the rpmbuild environment of the user
running the script, anyway, and I should not have been listed here.
If remote client send invalid data in request with "Transfer-Encoding:chunked" gunicorn can raised some exceptions (see http.body.ChunkedReader) as NoMoreData, ChunkMissingTerminator, InvalidChunkSize.
User application shouldn't know about specific gunicorn exceptions and must catch standard IOError if want.
Example:
def app(env, start_response):
body = env["wsgi.input"]
chunk_size = 1024
while True:
try:
chunk = body.read(chunk_size)
except IOError:
.. correct action for error
if not chunk:
break
.. do somethink with chunk
This will let a standard init script (or any script that look for a
pidfile) know that gunicorn is already running and won't attempt to run
it twice.
This would also enable the script to stop gunicorn even in it's startup
phase.
server.stop() are blocking worker and which is then may be killed by Arbiter.murder_workers() with timeout (not graceful_timeout). It's issues when graceful_timeout > timeout.
We were accidentally including partial data when we didn't find the
request line terminating '\r\n'. This changes the check to make sure
we're testing the length after we assert there's no termination.
Keepalive=0 means that we aren't waiting for the next connection. So
make sure to send appropriate "close" header and that we handle the first
connection.
1. client.getpeername() can raise "error: [Errno 107] Transport endpoint
is
not connected" if a client has unexpectedly disconnected.
2. I guess we do not need worry about sending error message to client.
We really shouldn't allow the people to override the way we spawn the
new workers on reload. Graceful is about launching new worker and kill
olders after the graceful time.