Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gunicorn worker #545

Merged
merged 11 commits into from
Mar 22, 2017
Merged

Gunicorn worker #545

merged 11 commits into from
Mar 22, 2017

Conversation

messense
Copy link
Contributor

@messense messense commented Mar 12, 2017

This is really just a WIP, it's working on the simple_server and try_everything example.

gunicorn simple_server:app --bind localhost:8000 --worker-class sanic.worker.GunicornWorker

Ping #61 #107 #501

@messense
Copy link
Contributor Author

Performance (MacBook Pro (Retina, 15-inch, Mid 2015)):

simple_server app.run with 4 workers:

wrk -c 4 -t 1 -d 30s http://localhost:8000/
Running 30s test @ http://localhost:8000/
  1 threads and 4 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency   124.63us  121.46us   6.21ms   99.11%
    Req/Sec    31.78k     5.25k   38.80k    52.82%
  951568 requests in 30.10s, 112.53MB read
Requests/sec:  31612.82
Transfer/sec:      3.74MB

simple_server Gunicorn with 4 workers:

wrk -c 4 -t 1 -d 30s http://localhost:8000/
Running 30s test @ http://localhost:8000/
  1 threads and 4 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency   120.28us   93.70us   5.86ms   99.12%
    Req/Sec    32.42k     4.65k   37.49k    68.00%
  967393 requests in 30.00s, 114.40MB read
Requests/sec:  32246.56
Transfer/sec:      3.81MB

@messense
Copy link
Contributor Author

The after_server_start and other events not working for now.

@r0fls
Copy link
Contributor

r0fls commented Mar 12, 2017

That's impressive that they're going the same speed. We saw a more significant slowdown when we implemented this. What benchmarks do you see with a single worker?

@messense
Copy link
Contributor Author

@r0fls

simple_server app.run with 1 worker:

wrk -c 4 -t 1 -d 30s http://localhost:8000/
Running 30s test @ http://localhost:8000/
  1 threads and 4 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency   165.06us   45.18us   3.79ms   96.53%
    Req/Sec    23.71k     1.06k   24.76k    90.03%
  710069 requests in 30.10s, 83.97MB read
Requests/sec:  23590.63
Transfer/sec:      2.79MB

simple_server Gunicorn with 1 worker:

wrk -c 4 -t 1 -d 30s http://localhost:8000/
Running 30s test @ http://localhost:8000/
  1 threads and 4 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency   185.10us  117.67us   6.28ms   96.74%
    Req/Sec    21.74k     2.71k   23.74k    86.71%
  651122 requests in 30.10s, 77.00MB read
Requests/sec:  21629.70
Transfer/sec:      2.56MB

if ssl is not None:
proto = "https"
log.info('Goin\' Fast @ {}://{}:{}'.format(proto, host, port))
if host and port:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will always be true because they have default values "127.0.0.1" and 8000

Copy link
Contributor Author

@messense messense Mar 13, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://docs.python.org/3/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.create_server

sock can optionally be specified in order to use a preexisting socket object. If specified, host and port should be omitted (must be None).

@r0fls r0fls requested a review from seemethere March 16, 2017 03:06
@messense
Copy link
Contributor Author

Mostly working now, websocket works but seems not closing on signal int while client still connected.

@messense
Copy link
Contributor Author

messense commented Mar 16, 2017

Actually, it won't shutdown in app.run mode with client still connected to websocket endpoint too.

Ping #469

@messense messense mentioned this pull request Mar 16, 2017
@miguelgrinberg
Copy link
Contributor

@messense yes, sanic simply waits for all connections to end, assuming they are short lived, but websocket will go on until the client goes away.

I'll think about how the websocket tasks can be signaled to exit.

@messense
Copy link
Contributor Author

I have extracted these changes into a package named sanic-gunicorn, feel free to try it.

If you guys don't want Gunicorn support in Sanic core, I'll close this PR and maintain the sanic-gunicorn package instead.

@r0fls
Copy link
Contributor

r0fls commented Mar 19, 2017

That sounds good. I'm fine with this change but I'm going to leave it up to @seemethere or @channelcat to make the ultimate decision.

@messense
Copy link
Contributor Author

messense commented Mar 20, 2017

@r0fls Either way, in order to support Gunicorn, Sanic app instance need to be a callable:

class Sanic:
    def __call__(self):
        return self

Edit: Add a dirty patch: messense/sanic-gunicorn@e60a683

@seemethere seemethere added this to the 0.5.0 milestone Mar 22, 2017
@seemethere seemethere merged commit 166f77c into sanic-org:master Mar 22, 2017
@seemethere
Copy link
Member

Documentation to go along with this would be amazing

@messense messense deleted the feature/gunicorn-worker branch March 23, 2017 01:01
zenixls2 pushed a commit to zenixls2/sanic that referenced this pull request Apr 11, 2017
zenixls2 pushed a commit to zenixls2/sanic that referenced this pull request Apr 11, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants