Skip to content

Commit

Permalink
Merge pull request #878 from 1st1/uvloop-gunicorn
Browse files Browse the repository at this point in the history
Implement a gunicorn worker that uses uvloop
  • Loading branch information
fafhrd91 committed May 17, 2016
2 parents 83fb7ec + 95c31ac commit 7a77fff
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 5 deletions.
3 changes: 3 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ install:
- pip install -r requirements-ci.txt
- pip install aiodns
- pip install coveralls
- if python -c "import sys; sys.exit(sys.version_info < (3,5))"; then
pip install uvloop;
fi

script:
- flake8 aiohttp
Expand Down
19 changes: 18 additions & 1 deletion aiohttp/worker.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

from aiohttp.helpers import ensure_future

__all__ = ('GunicornWebWorker',)
__all__ = ('GunicornWebWorker', 'GunicornUVLoopWebWorker')


class GunicornWebWorker(base.Worker):
Expand Down Expand Up @@ -141,3 +141,20 @@ def handle_quit(self, sig, frame):
def handle_abort(self, sig, frame):
self.alive = False
self.exit_code = 1


class GunicornUVLoopWebWorker(GunicornWebWorker):

def init_process(self):
import uvloop

# Close any existing event loop before setting a
# new policy.
asyncio.get_event_loop().close()

# Setup uvloop policy, so that every
# asyncio.get_event_loop() will create an instance
# of uvloop event loop.
asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())

super().init_process()
6 changes: 6 additions & 0 deletions docs/gunicorn.rst
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,12 @@ aiohttp.wsgi applications::
Gunicorn is now running and ready to serve requests to your app's
worker processes.

.. note::

If you want to use an alternative asyncio event loop
`uvloop <https://github.com/MagicStack/uvloop>`_, you can use the
``aiohttp.worker.GunicornUVLoopWebWorker`` worker class.


More information
----------------
Expand Down
26 changes: 22 additions & 4 deletions tests/test_worker.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
"""Tests for aiohttp/worker.py"""
import asyncio
import pytest
import sys
import unittest

from unittest import mock


base_worker = pytest.importorskip('aiohttp.worker')


class MyWorker(base_worker.GunicornWebWorker):
class BaseTestWorker:

def __init__(self):
self.servers = []
Expand All @@ -16,9 +19,24 @@ def __init__(self):
self.cfg.graceful_timeout = 100


@pytest.fixture
def worker():
return MyWorker()
class AsyncioWorker(BaseTestWorker, base_worker.GunicornWebWorker):
pass


class UvloopWorker(BaseTestWorker, base_worker.GunicornUVLoopWebWorker):

def __init__(self):
if sys.version_info < (3, 5) \
or sys.platform in ('win32', 'cygwin', 'cli'):
# uvloop requires Python 3.5 and *nix.
raise unittest.SkipTest()

super().__init__()


@pytest.fixture(params=[AsyncioWorker, UvloopWorker])
def worker(request):
return request.param()


def test_init_process(worker):
Expand Down

0 comments on commit 7a77fff

Please sign in to comment.