diff --git a/heat/engine/service.py b/heat/engine/service.py index b46994cf83..c22a0001f5 100644 --- a/heat/engine/service.py +++ b/heat/engine/service.py @@ -368,6 +368,7 @@ class EngineService(service.Service): self._client = rpc_messaging.get_rpc_client( version=self.RPC_API_VERSION) + self._configure_db_conn_pool_size() self.service_manage_cleanup() self.manage_thread_grp = threadgroup.ThreadGroup() self.manage_thread_grp.add_timer(cfg.CONF.periodic_interval, @@ -376,6 +377,18 @@ class EngineService(service.Service): super(EngineService, self).start() + def _configure_db_conn_pool_size(self): + # bug #1491185 + # Set the DB max_overflow to match the thread pool size. + # The overflow connections are automatically closed when they are + # not used; setting it is better than setting DB max_pool_size. + worker_pool_size = cfg.CONF.executor_thread_pool_size + # Update max_overflow only if it is not adequate + if ((cfg.CONF.database.max_overflow is None) or + (cfg.CONF.database.max_overflow < worker_pool_size)): + cfg.CONF.set_override('max_overflow', worker_pool_size, + group='database') + def _stop_rpc_server(self): # Stop rpc connection at first for preventing new requests LOG.debug("Attempting to stop engine service...") diff --git a/heat/tests/engine/service/test_service_engine.py b/heat/tests/engine/service/test_service_engine.py index 908a1cb929..18f338cfdd 100644 --- a/heat/tests/engine/service/test_service_engine.py +++ b/heat/tests/engine/service/test_service_engine.py @@ -230,8 +230,10 @@ class ServiceEngineTest(common.HeatTestCase): return_value=mock.Mock()) @mock.patch('oslo_service.threadgroup.ThreadGroup', return_value=mock.Mock()) + @mock.patch.object(service.EngineService, '_configure_db_conn_pool_size') def test_engine_service_start_in_non_convergence_mode( self, + configure_db_conn_pool_size, thread_group_class, engine_listener_class, thread_group_manager_class, @@ -267,8 +269,10 @@ class ServiceEngineTest(common.HeatTestCase): return_value=mock.Mock()) @mock.patch('oslo_service.threadgroup.ThreadGroup', return_value=mock.Mock()) + @mock.patch.object(service.EngineService, '_configure_db_conn_pool_size') def test_engine_service_start_in_convergence_mode( self, + configure_db_conn_pool_size, thread_group_class, worker_service_class, engine_listener_class, @@ -380,3 +384,30 @@ class ServiceEngineTest(common.HeatTestCase): def test_engine_service_reset(self, setup_logging_mock): self.eng.reset() setup_logging_mock.assert_called_once_with(cfg.CONF, 'heat') + + @mock.patch('oslo_messaging.Target', + return_value=mock.Mock()) + @mock.patch('heat.common.messaging.get_rpc_client', + return_value=mock.Mock()) + @mock.patch('heat.engine.stack_lock.StackLock.generate_engine_id', + return_value=mock.Mock()) + @mock.patch('heat.engine.service.ThreadGroupManager', + return_value=mock.Mock()) + @mock.patch('heat.engine.service.EngineListener', + return_value=mock.Mock()) + @mock.patch('heat.engine.worker.WorkerService', + return_value=mock.Mock()) + @mock.patch('oslo_service.threadgroup.ThreadGroup', + return_value=mock.Mock()) + def test_engine_service_configures_connection_pool( + self, + thread_group_class, + worker_service_class, + engine_listener_class, + thread_group_manager_class, + sample_uuid_method, + rpc_client_class, + target_class): + self.eng.start() + self.assertEqual(cfg.CONF.executor_thread_pool_size, + cfg.CONF.database.max_overflow)