ga4gh / ga4gh-server

Reference implementation of the APIs defined in ga4gh-schemas. RETIRED 2018-01-24
http://ga4gh.org
Apache License 2.0
96 stars 93 forks source link

Ship with a standalone WSGI server #1548

Open david4096 opened 7 years ago

david4096 commented 7 years ago

If you've ever set up Apache, then you know it can be a pain. We ship the server to run with the call ga4gh_server which uses the flask debug server, but when you set it up to run behind Apache it manages multiple processes better.

It is possible to ship the server with a "standalone" WSGI server. This means the call to ga4gh_server would by default handle multiple connections well and makes it suitable for most modest installations. We could still provide a path using the debug server via a flag.

This should make deployment much easier. You can still put the WSGI server behind apache or nginx using a proxy, it is easier to configure and doesn't require mod_wsgi.

http://stackoverflow.com/questions/20843486/what-are-the-limitations-of-the-flask-built-in-web-server

http://flask.pocoo.org/docs/0.12/deploying/wsgi-standalone/

kozbo commented 7 years ago

This comment from your first link is rather disconcerting.

Another issue is security: if you are concerned at ALL about security (and not just the security of the data in the application itself, but the security of the box that will be running it as well) then you should not use the development server. It is not ready to withstand any sort of attack.

The entire post strongly suggests that we should move away from using our current configuration. The guincorn server looks interesting.

david4096 commented 7 years ago

We can close this issue if the script server_dev, when not running in debug mode, starts the app behind gunicorn as opposed to SimpleHTTPServer.

david4096 commented 7 years ago

Being able to send and receive requests at the same time is a very visible feature when we are evaluating peer to peer features, which the debug server can't do. Took a quick look at this and made these two branches:

https://github.com/david4096/server-1/tree/gunicorn https://github.com/david4096/server-1/tree/twisted

I used minimal configuration and a synthetic test to simulate simultaneous queries. Since it is on the same machine, the number of source requests simultaneously sent is limited.

The script uses runs a lot of curl commands in the background

for i in {1..10000}; do
    curl -X POST http://localhost:8000/datasets/search --silent -O /dev/null &
done

1) ~360 requests/second https://github.com/david4096/server-1/tree/gunicorn

I think that the twisted library needs to be taken advantage of differently to realize its benefit (asynchronous communication). It seems to use a single process with multiple threads. Since it is managing the extra thread overhead it loses to the debug server, but if it had process management similar to gunicorn I believe it would be competitive.

The next steps are to add a configuration option to run with multiple workers, and to optionally specify the number of workers. The configuration path needs to be refactored slightly as some values are passed to the .run() method, and they should be set at an earlier config step if possible. Logging will behave differently when running under gunicorn, and so we'll have to determine the amount of test coverage we want/need when running under this mode. Tests that rely on bringing the server up and down appear to timeout right now.

It's worth noting the generally poor performance, I tried hitting a 404 endpoint 10k times in the same way and got similar performance, so serialization/deserialization doesn't play much role here. Also worth noting is the generally poor performance overall, if we want to get into thousands of requests per second we'll need to approach the frontend differently.

The test setup is not very well controlled, but the magnitude of the difference is pretty clear. If you see a flaw in the setup, please let me know. If you would like to experiment further feel free to fork from https://github.com/david4096/server-1/tree/gunicorn or https://github.com/david4096/server-1/tree/twisted .

Talks about a microframework built with twisted in mind, very similar to Flask - http://crossbario.com/blog/going-asynchronous-from-flask-to-twisted-klein/

The docs for klein in the above article - http://klein.readthedocs.io/en/latest/

(Old post) comparing python web frameworks - http://agiliq.com/blog/2010/11/i-am-so-starving-same-web-app-in-various-python-we/

I have heard good things about Tornado's performance http://www.tornadoweb.org/en/stable/