mirror of
https://github.com/sprockets/sprockets.http.git
synced 2024-11-14 19:29:28 +00:00
Merge pull request #24 from dave-shawley/reuse-that-address
Reuse the listening socket address
This commit is contained in:
commit
615577e092
10 changed files with 79 additions and 14 deletions
8
.readthedocs.yml
Normal file
8
.readthedocs.yml
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
---
|
||||||
|
formats: # only HTML & json
|
||||||
|
- none
|
||||||
|
requirements_file: requires/development.txt
|
||||||
|
build:
|
||||||
|
image: latest
|
||||||
|
python:
|
||||||
|
version: 3
|
|
@ -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
|
||||||
|
|
2
LICENSE
2
LICENSE
|
@ -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,
|
||||||
|
|
12
README.rst
12
README.rst
|
@ -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/
|
||||||
|
|
|
@ -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']
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
22
tests.py
22
tests.py
|
@ -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
27
tox.ini
|
@ -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}
|
||||||
|
|
Loading…
Reference in a new issue