Merge pull request #24 from dave-shawley/reuse-that-address

Reuse the listening socket address
This commit is contained in:
Gavin M. Roy 2018-01-29 11:26:21 -05:00 committed by GitHub
commit 615577e092
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 79 additions and 14 deletions

8
.readthedocs.yml Normal file
View file

@ -0,0 +1,8 @@
---
formats: # only HTML & json
- none
requirements_file: requires/development.txt
build:
image: latest
python:
version: 3

View file

@ -10,7 +10,6 @@ install:
- pip install -e . - pip install -e .
script: script:
- nosetests --with-coverage - nosetests --with-coverage
- ./setup.py build_sphinx
after_success: after_success:
- codecov - codecov
sudo: false sudo: false

View file

@ -1,4 +1,4 @@
Copyright (c) 2015-2016 AWeber Communications Copyright (c) 2015-2017 AWeber Communications
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, Redistribution and use in source and binary forms, with or without modification,

View file

@ -1,5 +1,8 @@
sprockets.http sprockets.http
============== ==============
|Version| |ReadTheDocs| |Travis| |Coverage|
The goal of this library is to make it a little easier to develop great The goal of this library is to make it a little easier to develop great
HTTP API services using the Tornado web framework. It concentrates on HTTP API services using the Tornado web framework. It concentrates on
running applications in a reliable & resilient manner and handling errors running applications in a reliable & resilient manner and handling errors
@ -235,3 +238,12 @@ the standard ``serve_traceback`` Tornado option is enabled.
If the ``sprockets.mixins.mediatype.ContentMixin`` is also extended by your If the ``sprockets.mixins.mediatype.ContentMixin`` is also extended by your
base class, ``write-error`` will use the ``ContentMixin.send_response`` method base class, ``write-error`` will use the ``ContentMixin.send_response`` method
for choosing the appropriate response format and sending the error response. for choosing the appropriate response format and sending the error response.
.. |Coverage| image:: https://codecov.io/github/sprockets/sprockets.http/coverage.svg?branch=master
:target: https://codecov.io/github/sprockets/sprockets.http
.. |ReadTheDocs| image:: http://readthedocs.org/projects/sprocketshttp/badge/?version=master
:target: https://sprocketshttp.readthedocs.io/
.. |Travis| image:: https://travis-ci.org/sprockets/sprockets.http.svg
:target: https://travis-ci.org/sprockets/sprockets.http
.. |Version| image:: https://badge.fury.io/py/sprockets.http.svg
:target: https://pypi.python.org/pypi/sprockets.http/

View file

@ -32,8 +32,6 @@ html_theme_options = {
'github_repo': 'sprockets.http', 'github_repo': 'sprockets.http',
'description': 'Tornado application runner', 'description': 'Tornado application runner',
'github_banner': True, 'github_banner': True,
'travis_button': True,
'codecov_button': True,
} }
html_static_path = ['_static'] html_static_path = ['_static']

View file

@ -3,8 +3,12 @@
Release History Release History
=============== ===============
`Next Release`_
---------------
- Enable port reuse for Tornado versions newer than 4.3.
`1.4.2`_ (25 Jan 2018) `1.4.2`_ (25 Jan 2018)
--------------------- ----------------------
- Allow max_body_size and max_buffer_size to be specified on the http server. - Allow max_body_size and max_buffer_size to be specified on the http server.
`1.4.1`_ (3 Jan 2018) `1.4.1`_ (3 Jan 2018)

View file

@ -1,6 +1,7 @@
-rinstallation.txt -rinstallation.txt
-rtesting.txt -rtesting.txt
coverage==4.4.2 coverage==4.4.2
flake8==3.5.0
sphinx==1.5.6 sphinx==1.5.6
sphinxcontrib-httpdomain==1.5.0 sphinxcontrib-httpdomain==1.5.0
tox==1.9.2 tox==1.9.2

View file

@ -12,6 +12,7 @@ import signal
import sys import sys
from tornado import httpserver, ioloop from tornado import httpserver, ioloop
import tornado
import sprockets.http.app import sprockets.http.app
@ -90,6 +91,11 @@ class Runner(object):
self.server.listen(port_number) self.server.listen(port_number)
else: else:
self.logger.info('starting processes on port %d', port_number) self.logger.info('starting processes on port %d', port_number)
if tornado.version_info >= (4, 4):
self.server.bind(port_number, reuse_port=True)
else:
self.logger.warning('port reuse disabled, please upgrade to'
'at least Tornado 4.4')
self.server.bind(port_number) self.server.bind(port_number)
self.server.start(number_of_procs) self.server.start(number_of_procs)
@ -125,7 +131,7 @@ class Runner(object):
try: try:
self.application.start(iol) self.application.start(iol)
except: except Exception:
self.logger.exception('application terminated during start, ' self.logger.exception('application terminated during start, '
'exiting') 'exiting')
sys.exit(70) sys.exit(70)

View file

@ -14,7 +14,8 @@ except ImportError:
import mock import mock
open_name = '__builtin__.open' open_name = '__builtin__.open'
from tornado import concurrent, httputil, ioloop, testing, web from tornado import concurrent, httpserver, httputil, ioloop, testing, web
import tornado
import sprockets.http.mixins import sprockets.http.mixins
import sprockets.http.runner import sprockets.http.runner
@ -383,7 +384,7 @@ class RunnerTests(MockHelper, unittest.TestCase):
ioloop_module = self.start_mock('sprockets.http.runner.ioloop') ioloop_module = self.start_mock('sprockets.http.runner.ioloop')
ioloop_module.IOLoop.instance.return_value = self.io_loop ioloop_module.IOLoop.instance.return_value = self.io_loop
self.http_server = mock.Mock() self.http_server = mock.Mock(spec=httpserver.HTTPServer)
self.httpserver_module = \ self.httpserver_module = \
self.start_mock('sprockets.http.runner.httpserver') self.start_mock('sprockets.http.runner.httpserver')
self.httpserver_module.HTTPServer.return_value = self.http_server self.httpserver_module.HTTPServer.return_value = self.http_server
@ -402,9 +403,24 @@ class RunnerTests(MockHelper, unittest.TestCase):
def test_that_production_run_starts_in_multiprocess_mode(self): def test_that_production_run_starts_in_multiprocess_mode(self):
runner = sprockets.http.runner.Runner(self.application) runner = sprockets.http.runner.Runner(self.application)
runner.run(8000) runner.run(8000)
self.http_server.bind.assert_called_once_with(8000)
self.assertTrue(self.http_server.bind.called)
args, kwargs = self.http_server.bind.call_args_list[0]
self.assertEqual(args, (8000, ))
self.http_server.start.assert_called_once_with(0) self.http_server.start.assert_called_once_with(0)
@unittest.skipUnless(tornado.version_info >= (4, 4),
'port reuse requries newer tornado')
def test_that_production_enables_reuse_port(self):
runner = sprockets.http.runner.Runner(self.application)
runner.run(8000)
self.assertTrue(self.http_server.bind.called)
args, kwargs = self.http_server.bind.call_args_list[0]
self.assertEqual(args, (8000, ))
self.assertEqual(kwargs['reuse_port'], True)
def test_that_debug_run_starts_in_singleprocess_mode(self): def test_that_debug_run_starts_in_singleprocess_mode(self):
self.application.settings['debug'] = True self.application.settings['debug'] = True
runner = sprockets.http.runner.Runner(self.application) runner = sprockets.http.runner.Runner(self.application)

27
tox.ini
View file

@ -1,13 +1,34 @@
[tox] [tox]
envlist = py27,py34,py35,pypy,pypy3 envlist = py27,py34,py35,pypy,pypy3,tornado42,tornado44,tornado45
indexserver = indexserver =
default = https://pypi.python.org/simple default = https://pypi.python.org/simple
toxworkdir = build/tox toxworkdir = build/tox
skip_missing_interpreters = True skip_missing_interpreters = True
use_develop = True
[testenv] [testenv]
commands = commands =
./setup.py develop nosetests -v
nosetests []
deps = deps =
-rrequires/testing.txt -rrequires/testing.txt
[testenv:tornado42]
commands =
{envbindir}/pip install tornado>=4.2,<4.3
{[testenv]commands}
[testenv:tornado43]
commands =
{envbindir}/pip install tornado>=4.3,<4.4
{[testenv]commands}
[testenv:tornado44]
commands =
{envbindir}/pip install tornado>=4.4,<4.5
{[testenv]commands}
[testenv:tornado45]
commands =
{envbindir}/pip install tornado>=4.5,<4.6
{[testenv]commands}