mirror of
https://github.com/frappe/gunicorn.git
synced 2026-01-14 11:09:11 +08:00
Merge pull request #882 from collinanderson/whitespace
clean whitespace
This commit is contained in:
commit
257e2228ae
@ -60,7 +60,7 @@ test suite on your branch before submitting a pull request.
|
|||||||
Make sure you include relevant updates or additions to documentation
|
Make sure you include relevant updates or additions to documentation
|
||||||
when creating or modifying features.
|
when creating or modifying features.
|
||||||
|
|
||||||
Write clean code.
|
Write clean code.
|
||||||
|
|
||||||
Pull requests descriptions should be as clear as possible and include a
|
Pull requests descriptions should be as clear as possible and include a
|
||||||
reference to all the issues that they address.
|
reference to all the issues that they address.
|
||||||
@ -147,8 +147,8 @@ benoitc.
|
|||||||
|
|
||||||
### How can I become a maintainer?
|
### How can I become a maintainer?
|
||||||
|
|
||||||
* Step 1: learn the component inside out
|
* Step 1: learn the component inside out
|
||||||
* Step 2: make yourself useful by contributing code, bugfixes, support etc.
|
* Step 2: make yourself useful by contributing code, bugfixes, support etc.
|
||||||
* Step 3: volunteer on the irc channel (#gunicorn@freenode)
|
* Step 3: volunteer on the irc channel (#gunicorn@freenode)
|
||||||
|
|
||||||
Don't forget: being a maintainer is a time investment. Make sure you
|
Don't forget: being a maintainer is a time investment. Make sure you
|
||||||
@ -160,8 +160,8 @@ maintainer to make a difference on the project!
|
|||||||
It is every maintainer's responsibility to:
|
It is every maintainer's responsibility to:
|
||||||
|
|
||||||
* 1) Expose a clear roadmap for improving their component.
|
* 1) Expose a clear roadmap for improving their component.
|
||||||
* 2) Deliver prompt feedback and decisions on pull requests.
|
* 2) Deliver prompt feedback and decisions on pull requests.
|
||||||
* 3) Be available to anyone with questions, bug reports, criticism etc. on their component. This includes irc, github requests and the mailing list.
|
* 3) Be available to anyone with questions, bug reports, criticism etc. on their component. This includes irc, github requests and the mailing list.
|
||||||
* 4) Make sure their component respects the philosophy, design and roadmap of the project.
|
* 4) Make sure their component respects the philosophy, design and roadmap of the project.
|
||||||
|
|
||||||
### How is this process changed?
|
### How is this process changed?
|
||||||
|
|||||||
@ -52,7 +52,7 @@ After installing Gunicorn you will have access to the command line script
|
|||||||
Commonly Used Arguments
|
Commonly Used Arguments
|
||||||
+++++++++++++++++++++++
|
+++++++++++++++++++++++
|
||||||
|
|
||||||
* ``-c CONFIG, --config=CONFIG`` - Specify the path to a `config file`_ or
|
* ``-c CONFIG, --config=CONFIG`` - Specify the path to a `config file`_ or
|
||||||
python module.
|
python module.
|
||||||
* ``-b BIND, --bind=BIND`` - Specify a server socket to bind. Server sockets
|
* ``-b BIND, --bind=BIND`` - Specify a server socket to bind. Server sockets
|
||||||
can be any of ``$(HOST)``, ``$(HOST):$(PORT)``, or ``unix:$(PATH)``.
|
can be any of ``$(HOST)``, ``$(HOST):$(PORT)``, or ``unix:$(PATH)``.
|
||||||
@ -147,7 +147,7 @@ Instrumentation
|
|||||||
---------------
|
---------------
|
||||||
|
|
||||||
Gunicorn provides an optional instrumentation of the arbiter and
|
Gunicorn provides an optional instrumentation of the arbiter and
|
||||||
workers using the statsD_ protocol over UDP. Thanks to the
|
workers using the statsD_ protocol over UDP. Thanks to the
|
||||||
`gunicorn.instrument.statsd` module, Gunicorn becomes a statsD client
|
`gunicorn.instrument.statsd` module, Gunicorn becomes a statsD client
|
||||||
The use of UDP cleanly isolates Gunicorn from the receiving end of the statsD
|
The use of UDP cleanly isolates Gunicorn from the receiving end of the statsD
|
||||||
metrics so that instrumentation does not cause Gunicorn to be held up by a slow
|
metrics so that instrumentation does not cause Gunicorn to be held up by a slow
|
||||||
|
|||||||
@ -15,5 +15,5 @@
|
|||||||
|
|
||||||
<!-- Exclude github CNAME file -->
|
<!-- Exclude github CNAME file -->
|
||||||
<filter action="drop" type="wildcard" pattern="*CNAME" />
|
<filter action="drop" type="wildcard" pattern="*CNAME" />
|
||||||
|
|
||||||
</site>
|
</site>
|
||||||
@ -291,7 +291,7 @@ class Encoder:
|
|||||||
# Something is seriously wrong if we get to here
|
# Something is seriously wrong if we get to here
|
||||||
return text.encode(ENC_ASCII, 'ignore')
|
return text.encode(ENC_ASCII, 'ignore')
|
||||||
#end def NarrowText
|
#end def NarrowText
|
||||||
|
|
||||||
def MaybeNarrowPath(self, text):
|
def MaybeNarrowPath(self, text):
|
||||||
""" Paths may be allowed to stay wide """
|
""" Paths may be allowed to stay wide """
|
||||||
if self._widefiles:
|
if self._widefiles:
|
||||||
@ -484,7 +484,7 @@ class URL(object):
|
|||||||
""" Do encoding and canonicalization on a URL string """
|
""" Do encoding and canonicalization on a URL string """
|
||||||
if not loc:
|
if not loc:
|
||||||
return loc
|
return loc
|
||||||
|
|
||||||
# Let the encoder try to narrow it
|
# Let the encoder try to narrow it
|
||||||
narrow = encoder.NarrowText(loc, None)
|
narrow = encoder.NarrowText(loc, None)
|
||||||
|
|
||||||
@ -545,7 +545,7 @@ class URL(object):
|
|||||||
def Validate(self, base_url, allow_fragment):
|
def Validate(self, base_url, allow_fragment):
|
||||||
""" Verify the data in this URL is well-formed, and override if not. """
|
""" Verify the data in this URL is well-formed, and override if not. """
|
||||||
assert type(base_url) == types.StringType
|
assert type(base_url) == types.StringType
|
||||||
|
|
||||||
# Test (and normalize) the ref
|
# Test (and normalize) the ref
|
||||||
if not self.loc:
|
if not self.loc:
|
||||||
output.Warn('Empty URL')
|
output.Warn('Empty URL')
|
||||||
@ -611,7 +611,7 @@ class URL(object):
|
|||||||
def Log(self, prefix='URL', level=3):
|
def Log(self, prefix='URL', level=3):
|
||||||
""" Dump the contents, empty or not, to the log. """
|
""" Dump the contents, empty or not, to the log. """
|
||||||
out = prefix + ':'
|
out = prefix + ':'
|
||||||
|
|
||||||
for attribute in self.__slots__:
|
for attribute in self.__slots__:
|
||||||
value = getattr(self, attribute)
|
value = getattr(self, attribute)
|
||||||
if not value:
|
if not value:
|
||||||
@ -636,7 +636,7 @@ class URL(object):
|
|||||||
value = str(value)
|
value = str(value)
|
||||||
value = xml.sax.saxutils.escape(value)
|
value = xml.sax.saxutils.escape(value)
|
||||||
out = out + (' <%s>%s</%s>\n' % (attribute, value, attribute))
|
out = out + (' <%s>%s</%s>\n' % (attribute, value, attribute))
|
||||||
|
|
||||||
out = out + SITEURL_XML_SUFFIX
|
out = out + SITEURL_XML_SUFFIX
|
||||||
file.write(out)
|
file.write(out)
|
||||||
#end def WriteXML
|
#end def WriteXML
|
||||||
@ -709,7 +709,7 @@ class Filter:
|
|||||||
""" Process the URL, as above. """
|
""" Process the URL, as above. """
|
||||||
if (not url) or (not url.loc):
|
if (not url) or (not url.loc):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
if self._wildcard:
|
if self._wildcard:
|
||||||
if fnmatch.fnmatchcase(url.loc, self._wildcard):
|
if fnmatch.fnmatchcase(url.loc, self._wildcard):
|
||||||
return self._pass
|
return self._pass
|
||||||
@ -738,7 +738,7 @@ class InputURL:
|
|||||||
if not ValidateAttributes('URL', attributes,
|
if not ValidateAttributes('URL', attributes,
|
||||||
('href', 'lastmod', 'changefreq', 'priority')):
|
('href', 'lastmod', 'changefreq', 'priority')):
|
||||||
return
|
return
|
||||||
|
|
||||||
url = URL()
|
url = URL()
|
||||||
for attr in attributes.keys():
|
for attr in attributes.keys():
|
||||||
if attr == 'href':
|
if attr == 'href':
|
||||||
@ -749,7 +749,7 @@ class InputURL:
|
|||||||
if not url.loc:
|
if not url.loc:
|
||||||
output.Error('Url entries must have an href attribute.')
|
output.Error('Url entries must have an href attribute.')
|
||||||
return
|
return
|
||||||
|
|
||||||
self._url = url
|
self._url = url
|
||||||
output.Log('Input: From URL "%s"' % self._url.loc, 2)
|
output.Log('Input: From URL "%s"' % self._url.loc, 2)
|
||||||
#end def __init__
|
#end def __init__
|
||||||
@ -775,7 +775,7 @@ class InputURLList:
|
|||||||
|
|
||||||
if not ValidateAttributes('URLLIST', attributes, ('path', 'encoding')):
|
if not ValidateAttributes('URLLIST', attributes, ('path', 'encoding')):
|
||||||
return
|
return
|
||||||
|
|
||||||
self._path = attributes.get('path')
|
self._path = attributes.get('path')
|
||||||
self._encoding = attributes.get('encoding', ENC_UTF8)
|
self._encoding = attributes.get('encoding', ENC_UTF8)
|
||||||
if self._path:
|
if self._path:
|
||||||
@ -808,7 +808,7 @@ class InputURLList:
|
|||||||
line = line.strip()
|
line = line.strip()
|
||||||
if (not line) or line[0] == '#':
|
if (not line) or line[0] == '#':
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Split the line on space
|
# Split the line on space
|
||||||
url = URL()
|
url = URL()
|
||||||
cols = line.split(' ')
|
cols = line.split(' ')
|
||||||
@ -1156,7 +1156,7 @@ class InputSitemap(xml.sax.handler.ContentHandler):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
class _ContextBase(object):
|
class _ContextBase(object):
|
||||||
|
|
||||||
"""Base class for context handlers in our SAX processing. A context
|
"""Base class for context handlers in our SAX processing. A context
|
||||||
handler is a class that is responsible for understanding one level of
|
handler is a class that is responsible for understanding one level of
|
||||||
depth in the XML schema. The class knows what sub-tags are allowed,
|
depth in the XML schema. The class knows what sub-tags are allowed,
|
||||||
@ -1165,7 +1165,7 @@ class InputSitemap(xml.sax.handler.ContentHandler):
|
|||||||
This base class is the API filled in by specific context handlers,
|
This base class is the API filled in by specific context handlers,
|
||||||
all defined below.
|
all defined below.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, subtags):
|
def __init__(self, subtags):
|
||||||
"""Initialize with a sequence of the sub-tags that would be valid in
|
"""Initialize with a sequence of the sub-tags that would be valid in
|
||||||
this context."""
|
this context."""
|
||||||
@ -1209,18 +1209,18 @@ class InputSitemap(xml.sax.handler.ContentHandler):
|
|||||||
#end class _ContextBase
|
#end class _ContextBase
|
||||||
|
|
||||||
class _ContextUrlSet(_ContextBase):
|
class _ContextUrlSet(_ContextBase):
|
||||||
|
|
||||||
"""Context handler for the document node in a Sitemap."""
|
"""Context handler for the document node in a Sitemap."""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
InputSitemap._ContextBase.__init__(self, ('url',))
|
InputSitemap._ContextBase.__init__(self, ('url',))
|
||||||
#end def __init__
|
#end def __init__
|
||||||
#end class _ContextUrlSet
|
#end class _ContextUrlSet
|
||||||
|
|
||||||
class _ContextUrl(_ContextBase):
|
class _ContextUrl(_ContextBase):
|
||||||
|
|
||||||
"""Context handler for a URL node in a Sitemap."""
|
"""Context handler for a URL node in a Sitemap."""
|
||||||
|
|
||||||
def __init__(self, consumer):
|
def __init__(self, consumer):
|
||||||
"""Initialize this context handler with the callable consumer that
|
"""Initialize this context handler with the callable consumer that
|
||||||
wants our URLs."""
|
wants our URLs."""
|
||||||
@ -1241,7 +1241,7 @@ class InputSitemap(xml.sax.handler.ContentHandler):
|
|||||||
self._consumer(self._url, False)
|
self._consumer(self._url, False)
|
||||||
self._url = None
|
self._url = None
|
||||||
#end def Close
|
#end def Close
|
||||||
|
|
||||||
def Return(self, result):
|
def Return(self, result):
|
||||||
"""A value context has closed, absorb the data it gave us."""
|
"""A value context has closed, absorb the data it gave us."""
|
||||||
assert self._url
|
assert self._url
|
||||||
@ -1251,9 +1251,9 @@ class InputSitemap(xml.sax.handler.ContentHandler):
|
|||||||
#end class _ContextUrl
|
#end class _ContextUrl
|
||||||
|
|
||||||
class _ContextSitemapIndex(_ContextBase):
|
class _ContextSitemapIndex(_ContextBase):
|
||||||
|
|
||||||
"""Context handler for the document node in an index file."""
|
"""Context handler for the document node in an index file."""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
InputSitemap._ContextBase.__init__(self, ('sitemap',))
|
InputSitemap._ContextBase.__init__(self, ('sitemap',))
|
||||||
self._loclist = [] # List of accumulated Sitemap URLs
|
self._loclist = [] # List of accumulated Sitemap URLs
|
||||||
@ -1271,7 +1271,7 @@ class InputSitemap(xml.sax.handler.ContentHandler):
|
|||||||
self._loclist = []
|
self._loclist = []
|
||||||
return temp
|
return temp
|
||||||
#end def Close
|
#end def Close
|
||||||
|
|
||||||
def Return(self, result):
|
def Return(self, result):
|
||||||
"""Getting a new loc URL, add it to the collection."""
|
"""Getting a new loc URL, add it to the collection."""
|
||||||
if result:
|
if result:
|
||||||
@ -1280,9 +1280,9 @@ class InputSitemap(xml.sax.handler.ContentHandler):
|
|||||||
#end class _ContextSitemapIndex
|
#end class _ContextSitemapIndex
|
||||||
|
|
||||||
class _ContextSitemap(_ContextBase):
|
class _ContextSitemap(_ContextBase):
|
||||||
|
|
||||||
"""Context handler for a Sitemap entry in an index file."""
|
"""Context handler for a Sitemap entry in an index file."""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
InputSitemap._ContextBase.__init__(self, ('loc', 'lastmod'))
|
InputSitemap._ContextBase.__init__(self, ('loc', 'lastmod'))
|
||||||
self._loc = None # The URL to the Sitemap
|
self._loc = None # The URL to the Sitemap
|
||||||
@ -1310,10 +1310,10 @@ class InputSitemap(xml.sax.handler.ContentHandler):
|
|||||||
#end class _ContextSitemap
|
#end class _ContextSitemap
|
||||||
|
|
||||||
class _ContextValue(_ContextBase):
|
class _ContextValue(_ContextBase):
|
||||||
|
|
||||||
"""Context handler for a single value. We return just the value. The
|
"""Context handler for a single value. We return just the value. The
|
||||||
higher level context has to remember what tag led into us."""
|
higher level context has to remember what tag led into us."""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
InputSitemap._ContextBase.__init__(self, ())
|
InputSitemap._ContextBase.__init__(self, ())
|
||||||
self._text = None
|
self._text = None
|
||||||
@ -1355,7 +1355,7 @@ class InputSitemap(xml.sax.handler.ContentHandler):
|
|||||||
|
|
||||||
if not ValidateAttributes('SITEMAP', attributes, ['path']):
|
if not ValidateAttributes('SITEMAP', attributes, ['path']):
|
||||||
return
|
return
|
||||||
|
|
||||||
# Init the first file path
|
# Init the first file path
|
||||||
path = attributes.get('path')
|
path = attributes.get('path')
|
||||||
if path:
|
if path:
|
||||||
@ -1388,7 +1388,7 @@ class InputSitemap(xml.sax.handler.ContentHandler):
|
|||||||
self._contexts_idx = [InputSitemap._ContextSitemapIndex(),
|
self._contexts_idx = [InputSitemap._ContextSitemapIndex(),
|
||||||
InputSitemap._ContextSitemap(),
|
InputSitemap._ContextSitemap(),
|
||||||
InputSitemap._ContextValue()]
|
InputSitemap._ContextValue()]
|
||||||
|
|
||||||
self._contexts_stm = [InputSitemap._ContextUrlSet(),
|
self._contexts_stm = [InputSitemap._ContextUrlSet(),
|
||||||
InputSitemap._ContextUrl(consumer),
|
InputSitemap._ContextUrl(consumer),
|
||||||
InputSitemap._ContextValue()]
|
InputSitemap._ContextValue()]
|
||||||
@ -1408,7 +1408,7 @@ class InputSitemap(xml.sax.handler.ContentHandler):
|
|||||||
def _ProcessFile(self, path):
|
def _ProcessFile(self, path):
|
||||||
"""Do per-file reading/parsing/consuming for the file path passed in."""
|
"""Do per-file reading/parsing/consuming for the file path passed in."""
|
||||||
assert path
|
assert path
|
||||||
|
|
||||||
# Open our file
|
# Open our file
|
||||||
(frame, file) = OpenFileForRead(path, 'SITEMAP')
|
(frame, file) = OpenFileForRead(path, 'SITEMAP')
|
||||||
if not file:
|
if not file:
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
Changelog - 2010
|
Changelog - 2010
|
||||||
================
|
================
|
||||||
|
|
||||||
0.12.0 / 2010-12-22
|
0.12.0 / 2010-12-22
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
- Add support for logging configuration using a ini file.
|
- Add support for logging configuration using a ini file.
|
||||||
@ -18,7 +18,7 @@ Changelog - 2010
|
|||||||
- Fix setpgrp issue, can now be launched via ubuntu upstart
|
- Fix setpgrp issue, can now be launched via ubuntu upstart
|
||||||
- Set the number of workers to zero on WINCH
|
- Set the number of workers to zero on WINCH
|
||||||
|
|
||||||
0.11.2 / 2010-10-30
|
0.11.2 / 2010-10-30
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
* Add SERVER_SOFTWARE to the os.environ
|
* Add SERVER_SOFTWARE to the os.environ
|
||||||
@ -30,7 +30,7 @@ Changelog - 2010
|
|||||||
* Fix HUP with Paster applications
|
* Fix HUP with Paster applications
|
||||||
* Fix readline in wsgi.input
|
* Fix readline in wsgi.input
|
||||||
|
|
||||||
0.11.1 / 2010-09-02
|
0.11.1 / 2010-09-02
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
* Implement max-requests feature to prevent memory leaks.
|
* Implement max-requests feature to prevent memory leaks.
|
||||||
@ -41,7 +41,7 @@ Changelog - 2010
|
|||||||
* Fix the default proc name internal setting.
|
* Fix the default proc name internal setting.
|
||||||
* Workaround to prevent Gevent worker to segfault on MacOSX.
|
* Workaround to prevent Gevent worker to segfault on MacOSX.
|
||||||
|
|
||||||
0.11.0 / 2010-08-12
|
0.11.0 / 2010-08-12
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
* Improve dramatically performances of Gevent and Eventlet workers
|
* Improve dramatically performances of Gevent and Eventlet workers
|
||||||
@ -49,7 +49,7 @@ Changelog - 2010
|
|||||||
* Drop Server and Date headers in start_response when provided.
|
* Drop Server and Date headers in start_response when provided.
|
||||||
* Fix latency issue in async workers
|
* Fix latency issue in async workers
|
||||||
|
|
||||||
0.10.1 / 2010-08-06
|
0.10.1 / 2010-08-06
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
* Improve gevent's workers. Add "egg:gunicorn#gevent_wsgi" worker using
|
* Improve gevent's workers. Add "egg:gunicorn#gevent_wsgi" worker using
|
||||||
@ -63,7 +63,7 @@ Changelog - 2010
|
|||||||
* Exit more quietly
|
* Exit more quietly
|
||||||
* Fix gevent dns issue
|
* Fix gevent dns issue
|
||||||
|
|
||||||
0.10.0 / 2010-07-08
|
0.10.0 / 2010-07-08
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
* New HTTP parser.
|
* New HTTP parser.
|
||||||
@ -84,7 +84,7 @@ Changelog - 2010
|
|||||||
* Internal refactoring and various bug fixes.
|
* Internal refactoring and various bug fixes.
|
||||||
* New documentation website.
|
* New documentation website.
|
||||||
|
|
||||||
0.9.1 / 2010-05-26
|
0.9.1 / 2010-05-26
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
* Support https via X-Forwarded-Protocol or X-Forwarded-Ssl headers
|
* Support https via X-Forwarded-Protocol or X-Forwarded-Ssl headers
|
||||||
@ -92,7 +92,7 @@ Changelog - 2010
|
|||||||
* Remove -d options which was used instead of -D for daemon.
|
* Remove -d options which was used instead of -D for daemon.
|
||||||
* Fix umask in unix socket
|
* Fix umask in unix socket
|
||||||
|
|
||||||
0.9.0 / 2010-05-24
|
0.9.0 / 2010-05-24
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
* Added *when_ready* hook. Called just after the server is started
|
* Added *when_ready* hook. Called just after the server is started
|
||||||
@ -104,7 +104,7 @@ Changelog - 2010
|
|||||||
* Fix reexec
|
* Fix reexec
|
||||||
* Documentation improvements
|
* Documentation improvements
|
||||||
|
|
||||||
0.8.1 / 2010-04-29
|
0.8.1 / 2010-04-29
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
* Fix builtins import in config
|
* Fix builtins import in config
|
||||||
@ -112,14 +112,14 @@ Changelog - 2010
|
|||||||
* Fix Tornado WSGI support
|
* Fix Tornado WSGI support
|
||||||
* Delay application loading until after processing all configuration
|
* Delay application loading until after processing all configuration
|
||||||
|
|
||||||
0.8.0 / 2010-04-22
|
0.8.0 / 2010-04-22
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
* Refactored Worker management for better async support. Now use the -k option
|
* Refactored Worker management for better async support. Now use the -k option
|
||||||
to set the type of request processing to use
|
to set the type of request processing to use
|
||||||
* Added support for Tornado_
|
* Added support for Tornado_
|
||||||
|
|
||||||
0.7.2 / 2010-04-15
|
0.7.2 / 2010-04-15
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
* Added --spew option to help debugging (installs a system trace hook)
|
* Added --spew option to help debugging (installs a system trace hook)
|
||||||
@ -131,7 +131,7 @@ Changelog - 2010
|
|||||||
|
|
||||||
* Fix bug when responses have no body.
|
* Fix bug when responses have no body.
|
||||||
|
|
||||||
0.7.0 / 2010-03-26
|
0.7.0 / 2010-03-26
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
* Added support for Eventlet_ and Gevent_ based workers.
|
* Added support for Eventlet_ and Gevent_ based workers.
|
||||||
@ -140,19 +140,19 @@ Changelog - 2010
|
|||||||
* Fix SIGWINCH on OpenBSD_
|
* Fix SIGWINCH on OpenBSD_
|
||||||
* Fix `PEP 333`_ compliance for the write callable.
|
* Fix `PEP 333`_ compliance for the write callable.
|
||||||
|
|
||||||
0.6.5 / 2010-03-11
|
0.6.5 / 2010-03-11
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
* Fix pidfile handling
|
* Fix pidfile handling
|
||||||
* Fix Exception Error
|
* Fix Exception Error
|
||||||
|
|
||||||
0.6.4 / 2010-03-08
|
0.6.4 / 2010-03-08
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
* Use cStringIO for performance when possible.
|
* Use cStringIO for performance when possible.
|
||||||
* Fix worker freeze when a remote connection closes unexpectedly.
|
* Fix worker freeze when a remote connection closes unexpectedly.
|
||||||
|
|
||||||
0.6.3 / 2010-03-07
|
0.6.3 / 2010-03-07
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
* Make HTTP parsing faster.
|
* Make HTTP parsing faster.
|
||||||
@ -168,7 +168,7 @@ Changelog - 2010
|
|||||||
* Improved performance when sending responses.
|
* Improved performance when sending responses.
|
||||||
* Workers are now murdered by age (the oldest is killed first).
|
* Workers are now murdered by age (the oldest is killed first).
|
||||||
|
|
||||||
0.6.1 / 2010-02-24
|
0.6.1 / 2010-02-24
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
* Added gunicorn config file support for Django admin command
|
* Added gunicorn config file support for Django admin command
|
||||||
@ -182,7 +182,7 @@ Changelog - 2010
|
|||||||
* Change privilege switch behavior. We now work like NGINX, master keeps the
|
* Change privilege switch behavior. We now work like NGINX, master keeps the
|
||||||
permissions, new uid/gid permissions are only set for workers.
|
permissions, new uid/gid permissions are only set for workers.
|
||||||
|
|
||||||
0.5.1 / 2010-02-22
|
0.5.1 / 2010-02-22
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
* Fix umask
|
* Fix umask
|
||||||
|
|||||||
@ -1,19 +1,19 @@
|
|||||||
Changelog - 2011
|
Changelog - 2011
|
||||||
================
|
================
|
||||||
|
|
||||||
0.13.4 / 2011-09-23
|
0.13.4 / 2011-09-23
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
- fix util.closerange function used to prevent leaking fds on python 2.5
|
- fix util.closerange function used to prevent leaking fds on python 2.5
|
||||||
(typo)
|
(typo)
|
||||||
|
|
||||||
0.13.3 / 2011-09-19
|
0.13.3 / 2011-09-19
|
||||||
-------------------
|
-------------------
|
||||||
- refactor gevent worker
|
- refactor gevent worker
|
||||||
- prevent leaking fds on reexec
|
- prevent leaking fds on reexec
|
||||||
- fix inverted request_time computation
|
- fix inverted request_time computation
|
||||||
|
|
||||||
0.13.2 / 2011-09-17
|
0.13.2 / 2011-09-17
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
- Add support for Tornado 2.0 in tornado worker
|
- Add support for Tornado 2.0 in tornado worker
|
||||||
@ -25,12 +25,12 @@ Changelog - 2011
|
|||||||
- Fix sendfile support
|
- Fix sendfile support
|
||||||
- Fix Django reloading
|
- Fix Django reloading
|
||||||
|
|
||||||
0.13.1 / 2011-08-22
|
0.13.1 / 2011-08-22
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
- Fix unix socket. log argument was missing.
|
- Fix unix socket. log argument was missing.
|
||||||
|
|
||||||
0.13.0 / 2011-08-22
|
0.13.0 / 2011-08-22
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
- Improve logging: allows file-reopening and add access log file
|
- Improve logging: allows file-reopening and add access log file
|
||||||
@ -58,7 +58,7 @@ Changelog - 2011
|
|||||||
- Fix django localisation
|
- Fix django localisation
|
||||||
- Compatible with gevent 0.14dev
|
- Compatible with gevent 0.14dev
|
||||||
|
|
||||||
0.12.1 / 2011-03-23
|
0.12.1 / 2011-03-23
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
- Add "on_starting" hook. This hook can be used to set anything before
|
- Add "on_starting" hook. This hook can be used to set anything before
|
||||||
|
|||||||
@ -31,5 +31,3 @@ Issue Tracking
|
|||||||
|
|
||||||
Bug reports, enhancement requests and tasks generally go in the `Github
|
Bug reports, enhancement requests and tasks generally go in the `Github
|
||||||
issue tracker <http://github.com/benoitc/gunicorn/issues>`_.
|
issue tracker <http://github.com/benoitc/gunicorn/issues>`_.
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -68,4 +68,3 @@ texinfo_documents = [
|
|||||||
u'Benoit Chesneau', 'Gunicorn', 'One line description of project.',
|
u'Benoit Chesneau', 'Gunicorn', 'One line description of project.',
|
||||||
'Miscellaneous'),
|
'Miscellaneous'),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@ -90,8 +90,8 @@ may be either threads or processes, wake up at the same time to handle a new
|
|||||||
request. Since only one handler will receive the request, the others will have
|
request. Since only one handler will receive the request, the others will have
|
||||||
been awakened for no reaon, wasting CPU cycles. At this time, Gunicorn does not
|
been awakened for no reaon, wasting CPU cycles. At this time, Gunicorn does not
|
||||||
implement any IPC solution for coordinating between worker processes. You may
|
implement any IPC solution for coordinating between worker processes. You may
|
||||||
experience high load due to this problem when using many workers or threads.
|
experience high load due to this problem when using many workers or threads.
|
||||||
However `a work has been started <https://github.com/benoitc/gunicorn/issues/792>`_
|
However `a work has been started <https://github.com/benoitc/gunicorn/issues/792>`_
|
||||||
to remove this issue.
|
to remove this issue.
|
||||||
|
|
||||||
.. _worker_class: configure.html#worker-class
|
.. _worker_class: configure.html#worker-class
|
||||||
@ -100,7 +100,7 @@ to remove this issue.
|
|||||||
Why I don't see any logs in the console?
|
Why I don't see any logs in the console?
|
||||||
----------------------------------------
|
----------------------------------------
|
||||||
|
|
||||||
Since the version R19, Gunicorn doesn't log by default in the console.
|
Since the version R19, Gunicorn doesn't log by default in the console.
|
||||||
To watch the logs in the console you now need to use the option ``--log-file=-``.
|
To watch the logs in the console you now need to use the option ``--log-file=-``.
|
||||||
|
|
||||||
Kernel Parameters
|
Kernel Parameters
|
||||||
|
|||||||
@ -940,4 +940,3 @@ statsd_host
|
|||||||
* ``None``
|
* ``None``
|
||||||
|
|
||||||
host:port of the statsd server to log to
|
host:port of the statsd server to log to
|
||||||
|
|
||||||
|
|||||||
@ -76,14 +76,14 @@ master process. It renames its .pid file to .oldbin (e.g.
|
|||||||
which in turn starts a new master process and the new worker processes::
|
which in turn starts a new master process and the new worker processes::
|
||||||
|
|
||||||
|
|
||||||
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
|
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
|
||||||
20844 benoitc 20 0 54808 11m 3352 S 0.0 0.1 0:00.36 gunicorn: master [test:app]
|
20844 benoitc 20 0 54808 11m 3352 S 0.0 0.1 0:00.36 gunicorn: master [test:app]
|
||||||
20849 benoitc 20 0 54808 9.9m 1500 S 0.0 0.1 0:00.02 gunicorn: worker [test:app]
|
20849 benoitc 20 0 54808 9.9m 1500 S 0.0 0.1 0:00.02 gunicorn: worker [test:app]
|
||||||
20850 benoitc 20 0 54808 9.9m 1500 S 0.0 0.1 0:00.01 gunicorn: worker [test:app]
|
20850 benoitc 20 0 54808 9.9m 1500 S 0.0 0.1 0:00.01 gunicorn: worker [test:app]
|
||||||
20851 benoitc 20 0 54808 9.9m 1500 S 0.0 0.1 0:00.01 gunicorn: worker [test:app]
|
20851 benoitc 20 0 54808 9.9m 1500 S 0.0 0.1 0:00.01 gunicorn: worker [test:app]
|
||||||
20854 benoitc 20 0 55748 12m 3348 S 0.0 0.2 0:00.35 gunicorn: master [test:app]
|
20854 benoitc 20 0 55748 12m 3348 S 0.0 0.2 0:00.35 gunicorn: master [test:app]
|
||||||
20859 benoitc 20 0 55748 11m 1500 S 0.0 0.1 0:00.01 gunicorn: worker [test:app]
|
20859 benoitc 20 0 55748 11m 1500 S 0.0 0.1 0:00.01 gunicorn: worker [test:app]
|
||||||
20860 benoitc 20 0 55748 11m 1500 S 0.0 0.1 0:00.00 gunicorn: worker [test:app]
|
20860 benoitc 20 0 55748 11m 1500 S 0.0 0.1 0:00.00 gunicorn: worker [test:app]
|
||||||
20861 benoitc 20 0 55748 11m 1500 S 0.0 0.1 0:00.01 gunicorn: worker [test:app]
|
20861 benoitc 20 0 55748 11m 1500 S 0.0 0.1 0:00.01 gunicorn: worker [test:app]
|
||||||
|
|
||||||
At this point, two instances of gunicorn are running, handling the
|
At this point, two instances of gunicorn are running, handling the
|
||||||
@ -106,8 +106,8 @@ If an update is successful and you want to keep the new server, send
|
|||||||
the TERM signal to the old master process to leave only the new server
|
the TERM signal to the old master process to leave only the new server
|
||||||
running::
|
running::
|
||||||
|
|
||||||
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
|
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
|
||||||
20854 benoitc 20 0 55748 12m 3348 S 0.0 0.2 0:00.45 gunicorn: master [test:app]
|
20854 benoitc 20 0 55748 12m 3348 S 0.0 0.2 0:00.45 gunicorn: master [test:app]
|
||||||
20859 benoitc 20 0 55748 11m 1500 S 0.0 0.1 0:00.02 gunicorn: worker [test:app]
|
20859 benoitc 20 0 55748 11m 1500 S 0.0 0.1 0:00.02 gunicorn: worker [test:app]
|
||||||
20860 benoitc 20 0 55748 11m 1500 S 0.0 0.1 0:00.02 gunicorn: worker [test:app]
|
20860 benoitc 20 0 55748 11m 1500 S 0.0 0.1 0:00.02 gunicorn: worker [test:app]
|
||||||
20861 benoitc 20 0 55748 11m 1500 S 0.0 0.1 0:00.01 gunicorn: worker [test:app]
|
20861 benoitc 20 0 55748 11m 1500 S 0.0 0.1 0:00.01 gunicorn: worker [test:app]
|
||||||
|
|||||||
@ -8,7 +8,7 @@
|
|||||||
#
|
#
|
||||||
# Single quoting is generally necessary for shell escape semantics.
|
# Single quoting is generally necessary for shell escape semantics.
|
||||||
#
|
#
|
||||||
# This file is part of gunicorn released under the MIT license.
|
# This file is part of gunicorn released under the MIT license.
|
||||||
# See the NOTICE for more information.
|
# See the NOTICE for more information.
|
||||||
|
|
||||||
def load(arg):
|
def load(arg):
|
||||||
@ -22,4 +22,3 @@ def load(arg):
|
|||||||
start_response(status, response_headers)
|
start_response(status, response_headers)
|
||||||
return iter([data])
|
return iter([data])
|
||||||
return app
|
return app
|
||||||
|
|
||||||
|
|||||||
@ -17,17 +17,17 @@
|
|||||||
|
|
||||||
</script>
|
</script>
|
||||||
<![endif]-->
|
<![endif]-->
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<header id="top">
|
<header id="top">
|
||||||
<h1>test app</h1>
|
<h1>test app</h1>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
{% block content %}{% endblock %}
|
|
||||||
|
|
||||||
|
|
||||||
|
{% block content %}{% endblock %}
|
||||||
<footer></footer>
|
|
||||||
|
|
||||||
|
|
||||||
|
<footer></footer>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@ -20,4 +20,3 @@ Another way to test that 1 + 1 is equal to 2.
|
|||||||
>>> 1 + 1 == 2
|
>>> 1 + 1 == 2
|
||||||
True
|
True
|
||||||
"""}
|
"""}
|
||||||
|
|
||||||
|
|||||||
@ -17,17 +17,17 @@
|
|||||||
|
|
||||||
</script>
|
</script>
|
||||||
<![endif]-->
|
<![endif]-->
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<header id="top">
|
<header id="top">
|
||||||
<h1>test app</h1>
|
<h1>test app</h1>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
{% block content %}{% endblock %}
|
|
||||||
|
|
||||||
|
|
||||||
|
{% block content %}{% endblock %}
|
||||||
<footer></footer>
|
|
||||||
|
|
||||||
|
|
||||||
|
<footer></footer>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@ -20,4 +20,3 @@ Another way to test that 1 + 1 is equal to 2.
|
|||||||
>>> 1 + 1 == 2
|
>>> 1 + 1 == 2
|
||||||
True
|
True
|
||||||
"""}
|
"""}
|
||||||
|
|
||||||
|
|||||||
@ -92,7 +92,7 @@ def use_setuptools(
|
|||||||
try:
|
try:
|
||||||
import pkg_resources
|
import pkg_resources
|
||||||
except ImportError:
|
except ImportError:
|
||||||
return do_download()
|
return do_download()
|
||||||
try:
|
try:
|
||||||
pkg_resources.require("setuptools>="+version); return
|
pkg_resources.require("setuptools>="+version); return
|
||||||
except pkg_resources.VersionConflict, e:
|
except pkg_resources.VersionConflict, e:
|
||||||
@ -268,9 +268,3 @@ if __name__=='__main__':
|
|||||||
update_md5(sys.argv[2:])
|
update_md5(sys.argv[2:])
|
||||||
else:
|
else:
|
||||||
main(sys.argv[1:])
|
main(sys.argv[1:])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -62,4 +62,3 @@ formatter = generic
|
|||||||
[formatter_generic]
|
[formatter_generic]
|
||||||
format = %(asctime)s,%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
|
format = %(asctime)s,%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
|
||||||
datefmt = %H:%M:%S
|
datefmt = %H:%M:%S
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!DOCTYPE html
|
<!DOCTYPE html
|
||||||
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||||
|
|||||||
@ -36,4 +36,3 @@ app = Application([
|
|||||||
(r"/", MainHandler),
|
(r"/", MainHandler),
|
||||||
(r"/longpoll", LongPollHandler)
|
(r"/longpoll", LongPollHandler)
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
# -*- coding: utf-8 -
|
# -*- coding: utf-8 -
|
||||||
#
|
#
|
||||||
# This file is part of gunicorn released under the MIT license.
|
# This file is part of gunicorn released under the MIT license.
|
||||||
# See the NOTICE for more information.
|
# See the NOTICE for more information.
|
||||||
#
|
#
|
||||||
# Example code from Eventlet sources
|
# Example code from Eventlet sources
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<!-- idea and code swiped from
|
<!-- idea and code swiped from
|
||||||
http://assorted.svn.sourceforge.net/viewvc/assorted/real-time-plotter/trunk/src/rtp.html?view=markup -->
|
http://assorted.svn.sourceforge.net/viewvc/assorted/real-time-plotter/trunk/src/rtp.html?view=markup -->
|
||||||
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.1/jquery.min.js"></script>
|
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.1/jquery.min.js"></script>
|
||||||
<script src="http://people.iola.dk/olau/flot/jquery.flot.js"></script>
|
<script src="http://people.iola.dk/olau/flot/jquery.flot.js"></script>
|
||||||
@ -9,7 +9,7 @@ http://assorted.svn.sourceforge.net/viewvc/assorted/real-time-plotter/trunk/src/
|
|||||||
window.onload = function() {
|
window.onload = function() {
|
||||||
var data = {};
|
var data = {};
|
||||||
var s = new WebSocket("ws://%(HTTP_HOST)s/data");
|
var s = new WebSocket("ws://%(HTTP_HOST)s/data");
|
||||||
s.onopen = function() {
|
s.onopen = function() {
|
||||||
//alert('open');
|
//alert('open');
|
||||||
s.send('hi');
|
s.send('hi');
|
||||||
};
|
};
|
||||||
|
|||||||
@ -87,8 +87,8 @@ class WebSocketWSGI(object):
|
|||||||
"Sec-WebSocket-Version: %s\r\n"
|
"Sec-WebSocket-Version: %s\r\n"
|
||||||
"Sec-WebSocket-Accept: %s\r\n\r\n"
|
"Sec-WebSocket-Accept: %s\r\n\r\n"
|
||||||
% (
|
% (
|
||||||
environ.get('HTTP_ORIGIN'),
|
environ.get('HTTP_ORIGIN'),
|
||||||
environ.get('HTTP_HOST'),
|
environ.get('HTTP_HOST'),
|
||||||
ws.path,
|
ws.path,
|
||||||
version,
|
version,
|
||||||
base64.b64encode(sha1(key + WS_KEY).digest())
|
base64.b64encode(sha1(key + WS_KEY).digest())
|
||||||
@ -99,8 +99,8 @@ class WebSocketWSGI(object):
|
|||||||
handshake_reply += (
|
handshake_reply += (
|
||||||
"WebSocket-Origin: %s\r\n"
|
"WebSocket-Origin: %s\r\n"
|
||||||
"WebSocket-Location: ws://%s%s\r\n\r\n" % (
|
"WebSocket-Location: ws://%s%s\r\n\r\n" % (
|
||||||
environ.get('HTTP_ORIGIN'),
|
environ.get('HTTP_ORIGIN'),
|
||||||
environ.get('HTTP_HOST'),
|
environ.get('HTTP_HOST'),
|
||||||
ws.path))
|
ws.path))
|
||||||
|
|
||||||
sock.sendall(handshake_reply)
|
sock.sendall(handshake_reply)
|
||||||
@ -194,7 +194,7 @@ class WebSocket(object):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
f = {'fin' : 0,
|
f = {'fin' : 0,
|
||||||
'opcode' : 0,
|
'opcode' : 0,
|
||||||
'mask' : 0,
|
'mask' : 0,
|
||||||
'hlen' : 2,
|
'hlen' : 2,
|
||||||
'length' : 0,
|
'length' : 0,
|
||||||
@ -343,10 +343,10 @@ class WebSocket(object):
|
|||||||
raise ValueError("Don't understand how to parse this type of message: %r" % buf)
|
raise ValueError("Don't understand how to parse this type of message: %r" % buf)
|
||||||
self._buf = buf
|
self._buf = buf
|
||||||
return msgs
|
return msgs
|
||||||
|
|
||||||
def send(self, message):
|
def send(self, message):
|
||||||
"""Send a message to the browser.
|
"""Send a message to the browser.
|
||||||
|
|
||||||
*message* should be convertable to a string; unicode objects should be
|
*message* should be convertable to a string; unicode objects should be
|
||||||
encodable as utf-8. Raises socket.error with errno of 32
|
encodable as utf-8. Raises socket.error with errno of 32
|
||||||
(broken pipe) if the socket has already been closed by the client."""
|
(broken pipe) if the socket has already been closed by the client."""
|
||||||
@ -364,8 +364,8 @@ class WebSocket(object):
|
|||||||
self._sendlock.put(t)
|
self._sendlock.put(t)
|
||||||
|
|
||||||
def wait(self):
|
def wait(self):
|
||||||
"""Waits for and deserializes messages.
|
"""Waits for and deserializes messages.
|
||||||
|
|
||||||
Returns a single message; the oldest not yet processed. If the client
|
Returns a single message; the oldest not yet processed. If the client
|
||||||
has already closed the connection, returns None. This is different
|
has already closed the connection, returns None. This is different
|
||||||
from normal socket behavior because the empty string is a valid
|
from normal socket behavior because the empty string is a valid
|
||||||
@ -415,7 +415,7 @@ class WebSocket(object):
|
|||||||
import os
|
import os
|
||||||
import random
|
import random
|
||||||
def handle(ws):
|
def handle(ws):
|
||||||
""" This is the websocket handler function. Note that we
|
""" This is the websocket handler function. Note that we
|
||||||
can dispatch based on path in here, too."""
|
can dispatch based on path in here, too."""
|
||||||
if ws.path == '/echo':
|
if ws.path == '/echo':
|
||||||
while True:
|
while True:
|
||||||
@ -423,19 +423,19 @@ def handle(ws):
|
|||||||
if m is None:
|
if m is None:
|
||||||
break
|
break
|
||||||
ws.send(m)
|
ws.send(m)
|
||||||
|
|
||||||
elif ws.path == '/data':
|
elif ws.path == '/data':
|
||||||
for i in xrange(10000):
|
for i in xrange(10000):
|
||||||
ws.send("0 %s %s\n" % (i, random.random()))
|
ws.send("0 %s %s\n" % (i, random.random()))
|
||||||
eventlet.sleep(0.1)
|
eventlet.sleep(0.1)
|
||||||
|
|
||||||
wsapp = WebSocketWSGI(handle)
|
wsapp = WebSocketWSGI(handle)
|
||||||
def app(environ, start_response):
|
def app(environ, start_response):
|
||||||
""" This resolves to the web page or the websocket depending on
|
""" This resolves to the web page or the websocket depending on
|
||||||
the path."""
|
the path."""
|
||||||
if environ['PATH_INFO'] == '/' or environ['PATH_INFO'] == "":
|
if environ['PATH_INFO'] == '/' or environ['PATH_INFO'] == "":
|
||||||
data = open(os.path.join(
|
data = open(os.path.join(
|
||||||
os.path.dirname(__file__),
|
os.path.dirname(__file__),
|
||||||
'websocket.html')).read()
|
'websocket.html')).read()
|
||||||
data = data % environ
|
data = data % environ
|
||||||
start_response('200 OK', [('Content-Type', 'text/html'),
|
start_response('200 OK', [('Content-Type', 'text/html'),
|
||||||
@ -443,4 +443,3 @@ def app(environ, start_response):
|
|||||||
return [data]
|
return [data]
|
||||||
else:
|
else:
|
||||||
return wsapp(environ, start_response)
|
return wsapp(environ, start_response)
|
||||||
|
|
||||||
|
|||||||
@ -6,7 +6,7 @@ import time
|
|||||||
max_mem = 100000
|
max_mem = 100000
|
||||||
|
|
||||||
class MemoryWatch(threading.Thread):
|
class MemoryWatch(threading.Thread):
|
||||||
|
|
||||||
def __init__(self, server, max_mem):
|
def __init__(self, server, max_mem):
|
||||||
super(MemoryWatch, self).__init__()
|
super(MemoryWatch, self).__init__()
|
||||||
self.daemon = True
|
self.daemon = True
|
||||||
@ -21,17 +21,17 @@ class MemoryWatch(threading.Thread):
|
|||||||
return -1
|
return -1
|
||||||
used_mem = sum(int(x) for x in out.split('\n')[1:])
|
used_mem = sum(int(x) for x in out.split('\n')[1:])
|
||||||
return used_mem
|
return used_mem
|
||||||
|
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
while True:
|
while True:
|
||||||
for (pid, worker) in list(self.server.WORKERS.items()):
|
for (pid, worker) in list(self.server.WORKERS.items()):
|
||||||
if self.memory_usage(pid) > self.max_mem:
|
if self.memory_usage(pid) > self.max_mem:
|
||||||
self.server.log.info("Pid %s killed (memory usage > %s)",
|
self.server.log.info("Pid %s killed (memory usage > %s)",
|
||||||
pid, self.max_mem)
|
pid, self.max_mem)
|
||||||
self.server.kill_worker(pid, signal.SIGTERM)
|
self.server.kill_worker(pid, signal.SIGTERM)
|
||||||
time.sleep(self.timeout)
|
time.sleep(self.timeout)
|
||||||
|
|
||||||
|
|
||||||
def when_ready(server):
|
def when_ready(server):
|
||||||
mw = MemoryWatch(server, max_mem)
|
mw = MemoryWatch(server, max_mem)
|
||||||
|
|||||||
@ -75,7 +75,7 @@ class Statsd(Logger):
|
|||||||
self.histogram(metric, value)
|
self.histogram(metric, value)
|
||||||
else:
|
else:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# Log to parent logger only if there is something to say
|
# Log to parent logger only if there is something to say
|
||||||
if msg is not None and len(msg) > 0:
|
if msg is not None and len(msg) > 0:
|
||||||
Logger.log(self, lvl, msg, *args, **kwargs)
|
Logger.log(self, lvl, msg, *args, **kwargs)
|
||||||
|
|||||||
@ -1 +0,0 @@
|
|||||||
|
|
||||||
@ -1 +0,0 @@
|
|||||||
|
|
||||||
@ -207,11 +207,11 @@ def test_cli_overrides_config_module():
|
|||||||
t.eq(app.cfg.proc_name, "fooey")
|
t.eq(app.cfg.proc_name, "fooey")
|
||||||
|
|
||||||
def test_default_config_file():
|
def test_default_config_file():
|
||||||
default_config = os.path.join(os.path.abspath(os.getcwd()),
|
default_config = os.path.join(os.path.abspath(os.getcwd()),
|
||||||
'gunicorn.conf.py')
|
'gunicorn.conf.py')
|
||||||
with open(default_config, 'w+') as default:
|
with open(default_config, 'w+') as default:
|
||||||
default.write("bind='0.0.0.0:9090'")
|
default.write("bind='0.0.0.0:9090'")
|
||||||
|
|
||||||
t.eq(config.get_default_config_file(), default_config)
|
t.eq(config.get_default_config_file(), default_config)
|
||||||
|
|
||||||
with AltArgs(["prog_name"]):
|
with AltArgs(["prog_name"]):
|
||||||
|
|||||||
@ -58,4 +58,3 @@ def test_readline_buffer_loaded_with_size():
|
|||||||
t.eq(body.readline(2), b"\n")
|
t.eq(body.readline(2), b"\n")
|
||||||
t.eq(body.readline(2), b"de")
|
t.eq(body.readline(2), b"de")
|
||||||
t.eq(body.readline(2), b"f")
|
t.eq(body.readline(2), b"f")
|
||||||
|
|
||||||
|
|||||||
@ -35,13 +35,13 @@ class SSLTestCase(TestCase):
|
|||||||
self.assertEquals(CertFile.section, 'Ssl')
|
self.assertEquals(CertFile.section, 'Ssl')
|
||||||
self.assertEquals(CertFile.cli, ['--certfile'])
|
self.assertEquals(CertFile.cli, ['--certfile'])
|
||||||
self.assertEquals(CertFile.default, None)
|
self.assertEquals(CertFile.default, None)
|
||||||
|
|
||||||
self.assertTrue(issubclass(SSLVersion, Setting))
|
self.assertTrue(issubclass(SSLVersion, Setting))
|
||||||
self.assertEquals(SSLVersion.name, 'ssl_version')
|
self.assertEquals(SSLVersion.name, 'ssl_version')
|
||||||
self.assertEquals(SSLVersion.section, 'Ssl')
|
self.assertEquals(SSLVersion.section, 'Ssl')
|
||||||
self.assertEquals(SSLVersion.cli, ['--ssl-version'])
|
self.assertEquals(SSLVersion.cli, ['--ssl-version'])
|
||||||
self.assertEquals(SSLVersion.default, ssl.PROTOCOL_TLSv1)
|
self.assertEquals(SSLVersion.default, ssl.PROTOCOL_TLSv1)
|
||||||
|
|
||||||
self.assertTrue(issubclass(CACerts, Setting))
|
self.assertTrue(issubclass(CACerts, Setting))
|
||||||
self.assertEquals(CACerts.name, 'ca_certs')
|
self.assertEquals(CACerts.name, 'ca_certs')
|
||||||
self.assertEquals(CACerts.section, 'Ssl')
|
self.assertEquals(CACerts.section, 'Ssl')
|
||||||
@ -55,7 +55,7 @@ class SSLTestCase(TestCase):
|
|||||||
self.assertEquals(SuppressRaggedEOFs.cli, ['--suppress-ragged-eofs'])
|
self.assertEquals(SuppressRaggedEOFs.cli, ['--suppress-ragged-eofs'])
|
||||||
self.assertEquals(SuppressRaggedEOFs.action, 'store_true')
|
self.assertEquals(SuppressRaggedEOFs.action, 'store_true')
|
||||||
self.assertEquals(SuppressRaggedEOFs.default, True)
|
self.assertEquals(SuppressRaggedEOFs.default, True)
|
||||||
|
|
||||||
self.assertTrue(issubclass(DoHandshakeOnConnect, Setting))
|
self.assertTrue(issubclass(DoHandshakeOnConnect, Setting))
|
||||||
self.assertEquals(DoHandshakeOnConnect.name, 'do_handshake_on_connect')
|
self.assertEquals(DoHandshakeOnConnect.name, 'do_handshake_on_connect')
|
||||||
self.assertEquals(DoHandshakeOnConnect.section, 'Ssl')
|
self.assertEquals(DoHandshakeOnConnect.section, 'Ssl')
|
||||||
@ -65,7 +65,7 @@ class SSLTestCase(TestCase):
|
|||||||
|
|
||||||
|
|
||||||
if sys.version_info >= (2, 7):
|
if sys.version_info >= (2, 7):
|
||||||
self.assertTrue(issubclass(Ciphers, Setting))
|
self.assertTrue(issubclass(Ciphers, Setting))
|
||||||
self.assertEquals(Ciphers.name, 'ciphers')
|
self.assertEquals(Ciphers.name, 'ciphers')
|
||||||
self.assertEquals(Ciphers.section, 'Ssl')
|
self.assertEquals(Ciphers.section, 'Ssl')
|
||||||
self.assertEquals(Ciphers.cli, ['--ciphers'])
|
self.assertEquals(Ciphers.cli, ['--ciphers'])
|
||||||
|
|||||||
@ -62,7 +62,7 @@ def test_instrument():
|
|||||||
t.eq(logger.sock.msgs[0], "gunicorn.test:666|g")
|
t.eq(logger.sock.msgs[0], "gunicorn.test:666|g")
|
||||||
t.eq(sio.getvalue(), "Blah\n") # log is unchanged
|
t.eq(sio.getvalue(), "Blah\n") # log is unchanged
|
||||||
logger.sock.reset()
|
logger.sock.reset()
|
||||||
|
|
||||||
# Debug logging also supports metrics
|
# Debug logging also supports metrics
|
||||||
logger.debug("", extra={"mtype": "gauge", "metric": "gunicorn.debug", "value": 667})
|
logger.debug("", extra={"mtype": "gauge", "metric": "gunicorn.debug", "value": 667})
|
||||||
t.eq(logger.sock.msgs[0], "gunicorn.debug:667|g")
|
t.eq(logger.sock.msgs[0], "gunicorn.debug:667|g")
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user