From 23fbee8dcd484fc46b320188b22ab6def0311679 Mon Sep 17 00:00:00 2001 From: zhurong Date: Tue, 9 Aug 2016 16:02:35 +0000 Subject: [PATCH] Add multiple api workers There is currently no way to specify the number of api workers, This patch add multiple api workers support. Change-Id: Id79cb7a3e056cf5ddc9967f2f26e1973f1473e8b Closes-Bug: #1603343 --- devstack/plugin.sh | 7 +- murano/cmd/api.py | 9 +-- murano/cmd/engine.py | 2 +- murano/common/config.py | 9 ++- murano/tests/unit/cmd/test_api_workers.py | 70 +++++++++++++++++++ murano/tests/unit/cmd/test_engine_workers.py | 4 +- ...multiple-api-workers-60492ddc2e3ff0aa.yaml | 6 ++ 7 files changed, 97 insertions(+), 10 deletions(-) create mode 100644 murano/tests/unit/cmd/test_api_workers.py create mode 100644 releasenotes/notes/multiple-api-workers-60492ddc2e3ff0aa.yaml diff --git a/devstack/plugin.sh b/devstack/plugin.sh index a76a7cff0..8f3b92f5c 100755 --- a/devstack/plugin.sh +++ b/devstack/plugin.sh @@ -204,9 +204,14 @@ function configure_murano { # Configure Murano API URL iniset $MURANO_CONF_FILE murano url "http://127.0.0.1:8082" + # Configure the number of api workers + if [[ -n "$MURANO_API_WORKERS" ]]; then + iniset $MURANO_CONF_FILE murano api_workers $MURANO_API_WORKERS + fi + # Configure the number of engine workers if [[ -n "$MURANO_ENGINE_WORKERS" ]]; then - iniset $MURANO_CONF_FILE engine workers $MURANO_ENGINE_WORKERS + iniset $MURANO_CONF_FILE engine engine_workers $MURANO_ENGINE_WORKERS fi if is_murano_backend_glare; then configure_murano_glare_backend diff --git a/murano/cmd/api.py b/murano/cmd/api.py index b45ce2e41..2ad1d234c 100644 --- a/murano/cmd/api.py +++ b/murano/cmd/api.py @@ -29,6 +29,7 @@ else: import sys +from oslo_concurrency import processutils from oslo_config import cfg from oslo_log import log as logging from oslo_service import service @@ -59,14 +60,14 @@ def main(): policy.init() logging.setup(CONF, 'murano') - launcher = service.ServiceLauncher(CONF) + workers = CONF.murano.api_workers + if not workers: + workers = processutils.get_worker_count() + launcher = service.launch(CONF, server.ApiService(), workers=workers) app = app_loader.load_paste_app('murano') port, host = (CONF.bind_port, CONF.bind_host) - launcher.launch_service(wsgi.Service(app, port, host)) - - launcher.launch_service(server.ApiService()) launcher.launch_service(server.NotificationService()) launcher.launch_service(stats.StatsCollectingService()) diff --git a/murano/cmd/engine.py b/murano/cmd/engine.py index 1c3f2a0fa..c524b5111 100644 --- a/murano/cmd/engine.py +++ b/murano/cmd/engine.py @@ -50,7 +50,7 @@ def main(): config.parse_args() logging.setup(CONF, 'murano') - workers = CONF.engine.workers + workers = CONF.engine.engine_workers if not workers: workers = processutils.get_worker_count() launcher = service.launch(CONF, diff --git a/murano/common/config.py b/murano/common/config.py index 8054bf52c..5ad703006 100644 --- a/murano/common/config.py +++ b/murano/common/config.py @@ -166,6 +166,9 @@ murano_opts = [ 'pagination request', deprecated_group='packages_opts'), + cfg.IntOpt('api_workers', + help=_('Number of API workers')), + ] networking_opts = [ @@ -220,8 +223,10 @@ engine_opts = [ cfg.IntOpt('agent_timeout', default=3600, help=_('Time for waiting for a response from murano agent ' 'during the deployment')), - cfg.IntOpt('workers', - help=_('Number of workers')), + cfg.IntOpt('engine_workers', + deprecated_opts=[cfg.DeprecatedOpt('workers', + group='engine')], + help=_('Number of engine workers')), cfg.ListOpt('load_packages_from', default=[], help=_('List of directories to load local packages from. ' diff --git a/murano/tests/unit/cmd/test_api_workers.py b/murano/tests/unit/cmd/test_api_workers.py new file mode 100644 index 000000000..2c37acea2 --- /dev/null +++ b/murano/tests/unit/cmd/test_api_workers.py @@ -0,0 +1,70 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import mock +import sys + +from oslo_concurrency import processutils +from oslo_config import cfg +from oslo_log import log as logging + +from murano.cmd import api +from murano.common import app_loader +from murano.common import config +from murano.common import policy +from murano.tests.unit import base + +CONF = cfg.CONF + + +class TestAPIWorkers(base.MuranoTestCase): + + def setUp(self): + super(TestAPIWorkers, self).setUp() + sys.argv = ['murano'] + + @mock.patch.object(config, 'parse_args') + @mock.patch.object(logging, 'setup') + @mock.patch.object(policy, 'init') + @mock.patch.object(config, 'set_middleware_defaults') + @mock.patch.object(app_loader, 'load_paste_app') + @mock.patch('oslo_service.service.launch') + def test_workers_default(self, launch, setup, parse_args, init, + load_paste_app, set_middleware_defaults): + api.main() + launch.assert_called_once_with(mock.ANY, mock.ANY, + workers=processutils.get_worker_count()) + + @mock.patch.object(config, 'parse_args') + @mock.patch.object(logging, 'setup') + @mock.patch.object(policy, 'init') + @mock.patch.object(config, 'set_middleware_defaults') + @mock.patch.object(app_loader, 'load_paste_app') + @mock.patch('oslo_service.service.launch') + def test_workers_good_setting(self, launch, setup, parse_args, init, + load_paste_app, set_middleware_defaults): + self.override_config("api_workers", 8, "murano") + api.main() + launch.assert_called_once_with(mock.ANY, mock.ANY, workers=8) + + @mock.patch.object(config, 'parse_args') + @mock.patch.object(logging, 'setup') + @mock.patch.object(policy, 'init') + @mock.patch.object(config, 'set_middleware_defaults') + @mock.patch.object(app_loader, 'load_paste_app') + @mock.patch('oslo_service.service.launch') + def test_workers_zero_setting(self, launch, setup, parse_args, init, + load_paste_app, set_middleware_defaults): + self.override_config("api_workers", 0, "murano") + api.main() + launch.assert_called_once_with(mock.ANY, mock.ANY, + workers=processutils.get_worker_count()) diff --git a/murano/tests/unit/cmd/test_engine_workers.py b/murano/tests/unit/cmd/test_engine_workers.py index 3fb788971..6a923b9d4 100644 --- a/murano/tests/unit/cmd/test_engine_workers.py +++ b/murano/tests/unit/cmd/test_engine_workers.py @@ -42,7 +42,7 @@ class TestEngineWorkers(base.MuranoTestCase): @mock.patch.object(logging, 'setup') @mock.patch('oslo_service.service.launch') def test_workers_good_setting(self, launch, setup, parse_args): - self.override_config("workers", 8, "engine") + self.override_config("engine_workers", 8, "engine") engine.main() launch.assert_called_once_with(mock.ANY, mock.ANY, workers=8) @@ -50,7 +50,7 @@ class TestEngineWorkers(base.MuranoTestCase): @mock.patch.object(logging, 'setup') @mock.patch('oslo_service.service.launch') def test_workers_zero_setting(self, launch, setup, parse_args): - self.override_config("workers", 0, "engine") + self.override_config("engine_workers", 0, "engine") engine.main() launch.assert_called_once_with(mock.ANY, mock.ANY, workers=processutils.get_worker_count()) diff --git a/releasenotes/notes/multiple-api-workers-60492ddc2e3ff0aa.yaml b/releasenotes/notes/multiple-api-workers-60492ddc2e3ff0aa.yaml new file mode 100644 index 000000000..cf4c785b4 --- /dev/null +++ b/releasenotes/notes/multiple-api-workers-60492ddc2e3ff0aa.yaml @@ -0,0 +1,6 @@ +--- +features: + - Add multiple api workers. +issues: + - Now too many server launch with api server at the same time, We should + refactor this to make API using the real specified workers.