mirror of
https://github.com/frappe/gunicorn.git
synced 2026-01-14 11:09:11 +08:00
This changes improve the binary upgrade behaviour using USR2: - only one binary upgrade can happen at a time: the old arbiter needs to be killed to promote the new arbiter. - if a new arbiter is already spawned, until one is killed USR2 has no action - if a new arbiter has been spawned, the unix socket won't be unlinked - until the old arbiter have been killed the newly created pidfile has the name <pidfile>.2 and the name Master.2 . Note: there is no dialog between both arbiters to handle this features. Instead they will supervise each others until one is killed. So isolation is still guaranted. fix #1267
80 lines
2.3 KiB
Python
80 lines
2.3 KiB
Python
# -*- coding: utf-8 -
|
|
#
|
|
# This file is part of gunicorn released under the MIT license.
|
|
# See the NOTICE for more information.
|
|
|
|
import os
|
|
|
|
try:
|
|
import unittest.mock as mock
|
|
except ImportError:
|
|
import mock
|
|
|
|
import gunicorn.app.base
|
|
import gunicorn.arbiter
|
|
|
|
|
|
class DummyApplication(gunicorn.app.base.BaseApplication):
|
|
"""
|
|
Dummy application that has an default configuration.
|
|
"""
|
|
|
|
def init(self, parser, opts, args):
|
|
"""No-op"""
|
|
|
|
def load(self):
|
|
"""No-op"""
|
|
|
|
def load_config(self):
|
|
"""No-op"""
|
|
|
|
|
|
def test_arbiter_shutdown_closes_listeners():
|
|
arbiter = gunicorn.arbiter.Arbiter(DummyApplication())
|
|
listener1 = mock.Mock()
|
|
listener2 = mock.Mock()
|
|
arbiter.LISTENERS = [listener1, listener2]
|
|
arbiter.stop()
|
|
listener1.close.assert_called_with()
|
|
listener2.close.assert_called_with()
|
|
|
|
|
|
class PreloadedAppWithEnvSettings(DummyApplication):
|
|
"""
|
|
Simple application that makes use of the 'preload' feature to
|
|
start the application before spawning worker processes and sets
|
|
environmental variable configuration settings.
|
|
"""
|
|
|
|
def load_config(self):
|
|
"""Set the 'preload_app' and 'raw_env' settings in order to verify their
|
|
interaction below.
|
|
"""
|
|
self.cfg.set('raw_env', [
|
|
'SOME_PATH=/tmp/something', 'OTHER_PATH=/tmp/something/else'])
|
|
self.cfg.set('preload_app', True)
|
|
|
|
def wsgi(self):
|
|
"""Assert that the expected environmental variables are set when
|
|
the main entry point of this application is called as part of a
|
|
'preloaded' application.
|
|
"""
|
|
verify_env_vars()
|
|
return super(PreloadedAppWithEnvSettings, self).wsgi()
|
|
|
|
|
|
def verify_env_vars():
|
|
assert os.getenv('SOME_PATH') == '/tmp/something'
|
|
assert os.getenv('OTHER_PATH') == '/tmp/something/else'
|
|
|
|
|
|
def test_env_vars_available_during_preload():
|
|
"""Ensure that configured environmental variables are set during the
|
|
initial set up of the application (called from the .setup() method of
|
|
the Arbiter) such that they are available during the initial loading
|
|
of the WSGI application.
|
|
"""
|
|
# Note that we aren't making any assertions here, they are made in the
|
|
# dummy application object being loaded here instead.
|
|
gunicorn.arbiter.Arbiter(PreloadedAppWithEnvSettings())
|