From bb870f861ab5c43fc7b7e91c69feadb7187c3bf1 Mon Sep 17 00:00:00 2001 From: Julien Danjou Date: Mon, 2 Nov 2015 15:43:42 +0100 Subject: [PATCH] Remove eventlet usage This entirely removes the eventlet usage. We do not monkey patch anything anymore. As far as messaging is concerned, what's used now is the threading executor. Change-Id: I42416e05671ef766ca2a8b326d84e7664e14de7d --- aodh/__init__.py | 7 -- aodh/cmd/{eventlet => }/alarm.py | 0 aodh/cmd/eventlet/__init__.py | 22 ----- aodh/cmd/{eventlet => }/storage.py | 0 aodh/messaging.py | 4 +- aodh/notifier/rest.py | 3 +- aodh/tests/base.py | 6 -- aodh/tests/unit/test_notifier.py | 137 +++++++++++++---------------- requirements.txt | 1 - setup.cfg | 10 +-- tox.ini | 2 - 11 files changed, 71 insertions(+), 121 deletions(-) rename aodh/cmd/{eventlet => }/alarm.py (100%) delete mode 100644 aodh/cmd/eventlet/__init__.py rename aodh/cmd/{eventlet => }/storage.py (100%) diff --git a/aodh/__init__.py b/aodh/__init__.py index 8753fef0c..51a51c31d 100644 --- a/aodh/__init__.py +++ b/aodh/__init__.py @@ -14,13 +14,6 @@ # License for the specific language governing permissions and limitations # under the License. -# This must be set before the initial import of eventlet because if -# dnspython is present in your environment then eventlet monkeypatches -# socket.getaddrinfo() with an implementation which doesn't work for IPv6. -import os - -os.environ['EVENTLET_NO_GREENDNS'] = 'yes' - class NotImplementedError(NotImplementedError): # FIXME(jd) This is used by WSME to return a correct HTTP code. We should diff --git a/aodh/cmd/eventlet/alarm.py b/aodh/cmd/alarm.py similarity index 100% rename from aodh/cmd/eventlet/alarm.py rename to aodh/cmd/alarm.py diff --git a/aodh/cmd/eventlet/__init__.py b/aodh/cmd/eventlet/__init__.py deleted file mode 100644 index 99efcc467..000000000 --- a/aodh/cmd/eventlet/__init__.py +++ /dev/null @@ -1,22 +0,0 @@ -# -*- encoding: utf-8 -*- -# -# Copyright 2014 OpenStack Foundation -# -# 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 eventlet -# NOTE(jd) We need to monkey patch the socket and select module for, -# at least, oslo.messaging, otherwise everything's blocked on its -# first read() or select(), thread need to be patched too, because -# oslo.messaging use threading.local -eventlet.monkey_patch(socket=True, select=True, thread=True, time=True) diff --git a/aodh/cmd/eventlet/storage.py b/aodh/cmd/storage.py similarity index 100% rename from aodh/cmd/eventlet/storage.py rename to aodh/cmd/storage.py diff --git a/aodh/messaging.py b/aodh/messaging.py index 425726bef..c0be2d8d4 100644 --- a/aodh/messaging.py +++ b/aodh/messaging.py @@ -50,7 +50,7 @@ def get_rpc_server(conf, transport, topic, endpoint): serializer = oslo_serializer.RequestContextSerializer( oslo_serializer.JsonPayloadSerializer()) return oslo_messaging.get_rpc_server(transport, target, - [endpoint], executor='eventlet', + [endpoint], executor='threading', serializer=serializer) @@ -68,7 +68,7 @@ def get_notification_listener(transport, targets, endpoints, allow_requeue=False): """Return a configured oslo_messaging notification listener.""" return oslo_messaging.get_notification_listener( - transport, targets, endpoints, executor='eventlet', + transport, targets, endpoints, executor='threading', allow_requeue=allow_requeue) diff --git a/aodh/notifier/rest.py b/aodh/notifier/rest.py index 4c114aa0e..9b7d9fbdc 100644 --- a/aodh/notifier/rest.py +++ b/aodh/notifier/rest.py @@ -14,7 +14,6 @@ # under the License. """Rest alarm notifier.""" -import eventlet from oslo_config import cfg from oslo_context import context from oslo_log import log @@ -102,4 +101,4 @@ class RestAlarmNotifier(notifier.AlarmNotifier): session = requests.Session() session.mount(action.geturl(), requests.adapters.HTTPAdapter(max_retries=max_retries)) - eventlet.spawn_n(session.post, action.geturl(), **kwargs) + session.post(action.geturl(), **kwargs) diff --git a/aodh/tests/base.py b/aodh/tests/base.py index a066fd250..11b3aee7e 100644 --- a/aodh/tests/base.py +++ b/aodh/tests/base.py @@ -18,7 +18,6 @@ import functools import os.path -import eventlet import oslo_messaging.conffixture from oslo_utils import timeutils from oslotest import base @@ -39,11 +38,6 @@ class BaseTestCase(base.BaseTestCase): exchange = 'aodh' conf.set_override("control_exchange", exchange) - # NOTE(sileht): oslo.messaging fake driver uses time.sleep - # for task switch, so we need to monkey_patch it - # and also ensure the correct exchange have been set - eventlet.monkey_patch(time=True, thread=True) - # NOTE(sileht): Ensure a new oslo.messaging driver is loaded # between each tests self.transport = messaging.get_transport(conf, "fake://", cache=False) diff --git a/aodh/tests/unit/test_notifier.py b/aodh/tests/unit/test_notifier.py index 6dc972a84..7a8c2cdc2 100644 --- a/aodh/tests/unit/test_notifier.py +++ b/aodh/tests/unit/test_notifier.py @@ -95,10 +95,6 @@ class TestAlarmNotifier(tests_base.BaseTestCase): 'alarm_id': 'foobar', 'condition': {'threshold': 42}}) - @staticmethod - def _fake_spawn_n(func, *args, **kwargs): - func(*args, **kwargs) - @staticmethod def _notification(action): notification = {} @@ -115,15 +111,14 @@ class TestAlarmNotifier(tests_base.BaseTestCase): def test_notify_alarm_rest_action_ok(self): action = 'http://host/action' - with mock.patch('eventlet.spawn_n', self._fake_spawn_n): - with mock.patch.object(requests.Session, 'post') as poster: - self.service.notify_alarm(context.get_admin_context(), - self._notification(action)) - poster.assert_called_with(action, data=mock.ANY, - headers=mock.ANY) - args, kwargs = poster.call_args - self.assertEqual(self.HTTP_HEADERS, kwargs['headers']) - self.assertEqual(DATA_JSON, jsonutils.loads(kwargs['data'])) + with mock.patch.object(requests.Session, 'post') as poster: + self.service.notify_alarm(context.get_admin_context(), + self._notification(action)) + poster.assert_called_with(action, data=mock.ANY, + headers=mock.ANY) + args, kwargs = poster.call_args + self.assertEqual(self.HTTP_HEADERS, kwargs['headers']) + self.assertEqual(DATA_JSON, jsonutils.loads(kwargs['data'])) def test_notify_alarm_rest_action_with_ssl_client_cert(self): action = 'https://host/action' @@ -131,16 +126,15 @@ class TestAlarmNotifier(tests_base.BaseTestCase): self.CONF.set_override("rest_notifier_certificate_file", certificate) - with mock.patch('eventlet.spawn_n', self._fake_spawn_n): - with mock.patch.object(requests.Session, 'post') as poster: - self.service.notify_alarm(context.get_admin_context(), - self._notification(action)) - poster.assert_called_with(action, data=mock.ANY, - headers=mock.ANY, - cert=certificate, verify=True) - args, kwargs = poster.call_args - self.assertEqual(self.HTTP_HEADERS, kwargs['headers']) - self.assertEqual(DATA_JSON, jsonutils.loads(kwargs['data'])) + with mock.patch.object(requests.Session, 'post') as poster: + self.service.notify_alarm(context.get_admin_context(), + self._notification(action)) + poster.assert_called_with(action, data=mock.ANY, + headers=mock.ANY, + cert=certificate, verify=True) + args, kwargs = poster.call_args + self.assertEqual(self.HTTP_HEADERS, kwargs['headers']) + self.assertEqual(DATA_JSON, jsonutils.loads(kwargs['data'])) def test_notify_alarm_rest_action_with_ssl_client_cert_and_key(self): action = 'https://host/action' @@ -150,62 +144,58 @@ class TestAlarmNotifier(tests_base.BaseTestCase): self.CONF.set_override("rest_notifier_certificate_file", certificate) self.CONF.set_override("rest_notifier_certificate_key", key) - with mock.patch('eventlet.spawn_n', self._fake_spawn_n): - with mock.patch.object(requests.Session, 'post') as poster: - self.service.notify_alarm(context.get_admin_context(), - self._notification(action)) - poster.assert_called_with(action, data=mock.ANY, - headers=mock.ANY, - cert=(certificate, key), verify=True) - args, kwargs = poster.call_args - self.assertEqual(self.HTTP_HEADERS, kwargs['headers']) - self.assertEqual(DATA_JSON, jsonutils.loads(kwargs['data'])) + with mock.patch.object(requests.Session, 'post') as poster: + self.service.notify_alarm(context.get_admin_context(), + self._notification(action)) + poster.assert_called_with(action, data=mock.ANY, + headers=mock.ANY, + cert=(certificate, key), verify=True) + args, kwargs = poster.call_args + self.assertEqual(self.HTTP_HEADERS, kwargs['headers']) + self.assertEqual(DATA_JSON, jsonutils.loads(kwargs['data'])) def test_notify_alarm_rest_action_with_ssl_verify_disable_by_cfg(self): action = 'https://host/action' self.CONF.set_override("rest_notifier_ssl_verify", False) - with mock.patch('eventlet.spawn_n', self._fake_spawn_n): - with mock.patch.object(requests.Session, 'post') as poster: - self.service.notify_alarm(context.get_admin_context(), - self._notification(action)) - poster.assert_called_with(action, data=mock.ANY, - headers=mock.ANY, - verify=False) - args, kwargs = poster.call_args - self.assertEqual(self.HTTP_HEADERS, kwargs['headers']) - self.assertEqual(DATA_JSON, jsonutils.loads(kwargs['data'])) + with mock.patch.object(requests.Session, 'post') as poster: + self.service.notify_alarm(context.get_admin_context(), + self._notification(action)) + poster.assert_called_with(action, data=mock.ANY, + headers=mock.ANY, + verify=False) + args, kwargs = poster.call_args + self.assertEqual(self.HTTP_HEADERS, kwargs['headers']) + self.assertEqual(DATA_JSON, jsonutils.loads(kwargs['data'])) def test_notify_alarm_rest_action_with_ssl_verify_disable(self): action = 'https://host/action?aodh-alarm-ssl-verify=0' - with mock.patch('eventlet.spawn_n', self._fake_spawn_n): - with mock.patch.object(requests.Session, 'post') as poster: - self.service.notify_alarm(context.get_admin_context(), - self._notification(action)) - poster.assert_called_with(action, data=mock.ANY, - headers=mock.ANY, - verify=False) - args, kwargs = poster.call_args - self.assertEqual(self.HTTP_HEADERS, kwargs['headers']) - self.assertEqual(DATA_JSON, jsonutils.loads(kwargs['data'])) + with mock.patch.object(requests.Session, 'post') as poster: + self.service.notify_alarm(context.get_admin_context(), + self._notification(action)) + poster.assert_called_with(action, data=mock.ANY, + headers=mock.ANY, + verify=False) + args, kwargs = poster.call_args + self.assertEqual(self.HTTP_HEADERS, kwargs['headers']) + self.assertEqual(DATA_JSON, jsonutils.loads(kwargs['data'])) def test_notify_alarm_rest_action_with_ssl_verify_enable_by_user(self): action = 'https://host/action?aodh-alarm-ssl-verify=1' self.CONF.set_override("rest_notifier_ssl_verify", False) - with mock.patch('eventlet.spawn_n', self._fake_spawn_n): - with mock.patch.object(requests.Session, 'post') as poster: - self.service.notify_alarm(context.get_admin_context(), - self._notification(action)) - poster.assert_called_with(action, data=mock.ANY, - headers=mock.ANY, - verify=True) - args, kwargs = poster.call_args - self.assertEqual(self.HTTP_HEADERS, kwargs['headers']) - self.assertEqual(DATA_JSON, jsonutils.loads(kwargs['data'])) + with mock.patch.object(requests.Session, 'post') as poster: + self.service.notify_alarm(context.get_admin_context(), + self._notification(action)) + poster.assert_called_with(action, data=mock.ANY, + headers=mock.ANY, + verify=True) + args, kwargs = poster.call_args + self.assertEqual(self.HTTP_HEADERS, kwargs['headers']) + self.assertEqual(DATA_JSON, jsonutils.loads(kwargs['data'])) @staticmethod def _fake_urlsplit(*args, **kwargs): @@ -249,14 +239,13 @@ class TestAlarmNotifier(tests_base.BaseTestCase): self.useFixture(mockpatch.Patch('keystoneclient.v3.client.Client', lambda **kwargs: client)) - with mock.patch('eventlet.spawn_n', self._fake_spawn_n): - with mock.patch.object(requests.Session, 'post') as poster: - self.service.notify_alarm(context.get_admin_context(), - self._notification(action)) - headers = {'X-Auth-Token': 'token_1234'} - headers.update(self.HTTP_HEADERS) - poster.assert_called_with( - url, data=mock.ANY, headers=mock.ANY) - args, kwargs = poster.call_args - self.assertEqual(headers, kwargs['headers']) - self.assertEqual(DATA_JSON, jsonutils.loads(kwargs['data'])) + with mock.patch.object(requests.Session, 'post') as poster: + self.service.notify_alarm(context.get_admin_context(), + self._notification(action)) + headers = {'X-Auth-Token': 'token_1234'} + headers.update(self.HTTP_HEADERS) + poster.assert_called_with( + url, data=mock.ANY, headers=mock.ANY) + args, kwargs = poster.call_args + self.assertEqual(headers, kwargs['headers']) + self.assertEqual(DATA_JSON, jsonutils.loads(kwargs['data'])) diff --git a/requirements.txt b/requirements.txt index 746fd5698..a30148225 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,7 +5,6 @@ alembic>=0.7.2 retrying!=1.3.0,>=1.2.3 # Apache-2.0 croniter>=0.3.4 # MIT License -eventlet>=0.17.4 jsonschema!=2.5.0,<3.0.0,>=2.0.0 keystonemiddleware>=2.2.0 lxml>=2.3 diff --git a/setup.cfg b/setup.cfg index 83029501a..d768f7633 100644 --- a/setup.cfg +++ b/setup.cfg @@ -60,11 +60,11 @@ aodh.notifier = console_scripts = aodh-api = aodh.cmd.api:main - aodh-dbsync = aodh.cmd.eventlet.storage:dbsync - aodh-expirer = aodh.cmd.eventlet.storage:expirer - aodh-evaluator = aodh.cmd.eventlet.alarm:evaluator - aodh-notifier = aodh.cmd.eventlet.alarm:notifier - aodh-listener = aodh.cmd.eventlet.alarm:listener + aodh-dbsync = aodh.cmd.storage:dbsync + aodh-expirer = aodh.cmd.storage:expirer + aodh-evaluator = aodh.cmd.alarm:evaluator + aodh-notifier = aodh.cmd.alarm:notifier + aodh-listener = aodh.cmd.alarm:listener oslo.config.opts = aodh = aodh.opts:list_opts diff --git a/tox.ini b/tox.ini index 181b1f3a1..d6bd77568 100644 --- a/tox.ini +++ b/tox.ini @@ -9,7 +9,6 @@ deps = -r{toxinidir}/requirements.txt install_command = pip install -U {opts} {packages} usedevelop = True setenv = VIRTUAL_ENV={envdir} - EVENTLET_NO_GREENDNS=yes OS_TEST_PATH=aodh/tests/unit passenv = OS_TEST_TIMEOUT OS_STDOUT_CAPTURE OS_STDERR_CAPTURE OS_LOG_CAPTURE commands = @@ -38,7 +37,6 @@ commands = [testenv:functional] setenv = VIRTUAL_ENV={envdir} - EVENTLET_NO_GREENDNS=yes OS_TEST_PATH=aodh/tests/functional/ GABBI_LIVE_FAIL_IF_NO_TEST=1 passenv = {[testenv]passenv} AODH_*