From b462a3b8cd0ccbf374dd140315ec1c431a8546be Mon Sep 17 00:00:00 2001 From: wangbo Date: Mon, 26 Dec 2016 13:50:03 +0800 Subject: [PATCH] Support magnum-api multiple process workers Multiple process workers support for magnum-api. Adds new option 'workers' to group [api] of magnum.conf. Change-Id: I0e8327ada6926602d577d1f36d384dd49426c7ee Implements: blueprint magnum-multiple-process-workers --- magnum/cmd/api.py | 8 +++++++- magnum/conf/api.py | 5 ++++- magnum/tests/unit/cmd/test_api.py | 25 ++++++++++++++++++++++++- 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/magnum/cmd/api.py b/magnum/cmd/api.py index 41e54d1211..92d7863836 100644 --- a/magnum/cmd/api.py +++ b/magnum/cmd/api.py @@ -17,6 +17,7 @@ import os import sys +from oslo_concurrency import processutils from oslo_log import log as logging from oslo_reports import guru_meditation_report as gmr from werkzeug import serving @@ -75,5 +76,10 @@ def main(): LOG.info(_LI('Serving on %(proto)s://%(host)s:%(port)s'), dict(proto="https" if use_ssl else "http", host=host, port=port)) - serving.run_simple(host, port, app, + workers = CONF.api.workers + if not workers: + workers = processutils.get_worker_count() + LOG.info(_LI('Server will handle each request in a new process up to' + ' %s concurrent processes'), workers) + serving.run_simple(host, port, app, processes=workers, ssl_context=_get_ssl_configs(use_ssl)) diff --git a/magnum/conf/api.py b/magnum/conf/api.py index 11756c9191..0df0da88cb 100644 --- a/magnum/conf/api.py +++ b/magnum/conf/api.py @@ -39,7 +39,10 @@ api_service_opts = [ "effect. "), cfg.BoolOpt('enabled_ssl', default=False, - help='Enable SSL Magnum API service') + help='Enable SSL Magnum API service'), + cfg.IntOpt('workers', + help='The maximum number of magnum-api processes to ' + 'fork and run. Default to number of CPUs on the host.') ] diff --git a/magnum/tests/unit/cmd/test_api.py b/magnum/tests/unit/cmd/test_api.py index e6ce096902..ea55eadbf7 100644 --- a/magnum/tests/unit/cmd/test_api.py +++ b/magnum/tests/unit/cmd/test_api.py @@ -14,6 +14,8 @@ import mock +from oslo_concurrency import processutils + from magnum.cmd import api from magnum.tests import base @@ -32,9 +34,28 @@ class TestMagnumAPI(base.TestCase): app = mock_app.load_app.return_value mock_prep.assert_called_once_with(mock.ANY) mock_app.load_app.assert_called_once_with() + workers = processutils.get_worker_count() mock_run.assert_called_once_with(base.CONF.api.host, base.CONF.api.port, - app, ssl_context=None) + app, processes=workers, + ssl_context=None) + + @mock.patch('werkzeug.serving.run_simple') + @mock.patch.object(api, 'api_app') + @mock.patch('magnum.common.service.prepare_service') + def test_api_http_config_workers(self, mock_prep, mock_app, + mock_run, mock_base): + fake_workers = 8 + self.config(workers=fake_workers, group='api') + api.main() + + app = mock_app.load_app.return_value + mock_prep.assert_called_once_with(mock.ANY) + mock_app.load_app.assert_called_once_with() + mock_run.assert_called_once_with(base.CONF.api.host, + base.CONF.api.port, + app, processes=fake_workers, + ssl_context=None) @mock.patch('os.path.exists') @mock.patch('werkzeug.serving.run_simple') @@ -91,6 +112,8 @@ class TestMagnumAPI(base.TestCase): mock_app.load_app.assert_called_once_with() mock_exist.assert_has_calls([mock.call('tmp_crt'), mock.call('tmp_key')]) + workers = processutils.get_worker_count() mock_run.assert_called_once_with(base.CONF.api.host, base.CONF.api.port, app, + processes=workers, ssl_context=('tmp_crt', 'tmp_key'))