Add hacking check for eventlet.spawn()

Change Id52c30bb5ded2184d772e6026b0f04f9a0efeb55 added a hacking check
for greenthread.spawn(). Since eventlet.spawn() calls
greenthread.spawn() under the covers, it should also be checked. Because
there are still occurrences of eventlet.spawn(), these were also cleaned
up in order to pass the added hacking check.

Co-Authored-By: Qin Zhao <chaochin@gmail.com>

Change-Id: Ia125b4ad5e84bf48091af5a7a483b89629f0ec31
Related-Bug: #1404268
Closes-Bug: #1468513
This commit is contained in:
Ryan Rossiter
2015-06-25 14:41:49 +00:00
parent a013f9d71b
commit 6179854ae7
11 changed files with 40 additions and 27 deletions
+1 -1
View File
@@ -50,7 +50,7 @@ Nova Specific Commandments
assertEqual(A in B, False) or assertEqual(False, A in B) to the more specific assertEqual(A in B, False) or assertEqual(False, A in B) to the more specific
assertIn/NotIn(A, B) assertIn/NotIn(A, B)
- [N339] Check common raise_feature_not_supported() is used for v2.1 HTTPNotImplemented response. - [N339] Check common raise_feature_not_supported() is used for v2.1 HTTPNotImplemented response.
- [N340] Check nova.utils.spawn() is used instead of greenthread.spawn() - [N340] Check nova.utils.spawn() is used instead of greenthread.spawn() and eventlet.spawn()
Creating Unit Tests Creating Unit Tests
------------------- -------------------
+12 -8
View File
@@ -96,8 +96,8 @@ api_version_re = re.compile(r"@.*api_version")
dict_constructor_with_list_copy_re = re.compile(r".*\bdict\((\[)?(\(|\[)") dict_constructor_with_list_copy_re = re.compile(r".*\bdict\((\[)?(\(|\[)")
decorator_re = re.compile(r"@.*") decorator_re = re.compile(r"@.*")
http_not_implemented_re = re.compile(r"raise .*HTTPNotImplemented\(") http_not_implemented_re = re.compile(r"raise .*HTTPNotImplemented\(")
greenthread_spawn_re = re.compile(r".*greenthread.spawn\(.*\)") spawn_re = re.compile(
greenthread_spawn_n_re = re.compile(r".*greenthread.spawn_n\(.*\)") r".*(eventlet|greenthread)\.(?P<spawn_part>spawn(_n)?)\(.*\)")
class BaseASTChecker(ast.NodeVisitor): class BaseASTChecker(ast.NodeVisitor):
@@ -523,16 +523,20 @@ def check_http_not_implemented(logical_line, physical_line, filename):
def check_greenthread_spawns(logical_line, physical_line, filename): def check_greenthread_spawns(logical_line, physical_line, filename):
"""Check for use of greenthread.spawn() and greenthread.spawn_n() """Check for use of greenthread.spawn(), greenthread.spawn_n(),
eventlet.spawn(), and eventlet.spawn_n()
N340 N340
""" """
msg = ("N340: Use nova.utils.%(spawn)s() rather than " msg = ("N340: Use nova.utils.%(spawn)s() rather than "
"greenthread.%(spawn)s()") "greenthread.%(spawn)s() and eventlet.%(spawn)s()")
if re.match(greenthread_spawn_re, logical_line): if "nova/utils.py" in filename or "nova/tests/" in filename:
yield (0, msg % {'spawn': 'spawn'}) return
if re.match(greenthread_spawn_n_re, logical_line):
yield (0, msg % {'spawn': 'spawn_n'}) match = re.match(spawn_re, logical_line)
if match:
yield (0, msg % {'spawn': match.group('spawn_part')})
def factory(register): def factory(register):
+1 -2
View File
@@ -24,7 +24,6 @@ import tarfile
import tempfile import tempfile
import boto.s3.connection import boto.s3.connection
import eventlet
from lxml import etree from lxml import etree
from oslo_concurrency import processutils from oslo_concurrency import processutils
from oslo_config import cfg from oslo_config import cfg
@@ -385,7 +384,7 @@ class S3ImageService(object):
LOG.info(_LI("Image %s was deleted underneath us"), image_uuid) LOG.info(_LI("Image %s was deleted underneath us"), image_uuid)
return return
eventlet.spawn_n(delayed_create) utils.spawn_n(delayed_create)
return image return image
+2 -3
View File
@@ -32,7 +32,6 @@ import math
import re import re
import uuid import uuid
import eventlet
import netaddr import netaddr
from oslo_config import cfg from oslo_config import cfg
from oslo_log import log as logging from oslo_log import log as logging
@@ -184,7 +183,7 @@ class RPCAllocateFixedIP(object):
network_p) network_p)
if host != self.host: if host != self.host:
# need to call allocate_fixed_ip to correct network host # need to call allocate_fixed_ip to correct network host
green_threads.append(eventlet.spawn( green_threads.append(utils.spawn(
self.network_rpcapi._rpc_allocate_fixed_ip, self.network_rpcapi._rpc_allocate_fixed_ip,
context, instance_id, network['id'], address, vpn, context, instance_id, network['id'], address, vpn,
host)) host))
@@ -1516,7 +1515,7 @@ class NetworkManager(manager.Manager):
call_func(context, network) call_func(context, network)
else: else:
# i'm not the right host, run call on correct host # i'm not the right host, run call on correct host
green_threads.append(eventlet.spawn( green_threads.append(utils.spawn(
self.network_rpcapi.rpc_setup_network_on_host, context, self.network_rpcapi.rpc_setup_network_on_host, context,
network.id, teardown, host)) network.id, teardown, host))
+2 -2
View File
@@ -15,13 +15,13 @@
import functools import functools
import eventlet
import netaddr import netaddr
from oslo_serialization import jsonutils from oslo_serialization import jsonutils
import six import six
from nova import exception from nova import exception
from nova.i18n import _ from nova.i18n import _
from nova import utils
def ensure_string_keys(d): def ensure_string_keys(d):
@@ -484,7 +484,7 @@ class NetworkInfoAsyncWrapper(NetworkInfo):
""" """
def __init__(self, async_method, *args, **kwargs): def __init__(self, async_method, *args, **kwargs):
self._gt = eventlet.spawn(async_method, *args, **kwargs) self._gt = utils.spawn(async_method, *args, **kwargs)
methods = ['json', 'fixed_ips', 'floating_ips'] methods = ['json', 'fixed_ips', 'floating_ips']
for method in methods: for method in methods:
fn = getattr(self, method) fn = getattr(self, method)
+8
View File
@@ -550,6 +550,14 @@ class HackingTestCase(test.NoDBTestCase):
self._assert_has_errors(code, checks.check_greenthread_spawns, self._assert_has_errors(code, checks.check_greenthread_spawns,
expected_errors=errors) expected_errors=errors)
code = "eventlet.spawn(func, arg1, kwarg1=kwarg1)"
self._assert_has_errors(code, checks.check_greenthread_spawns,
expected_errors=errors)
code = "eventlet.spawn_n(func, arg1, kwarg1=kwarg1)"
self._assert_has_errors(code, checks.check_greenthread_spawns,
expected_errors=errors)
code = "nova.utils.spawn(func, arg1, kwarg1=kwarg1)" code = "nova.utils.spawn(func, arg1, kwarg1=kwarg1)"
self._assert_has_no_errors(code, checks.check_greenthread_spawns) self._assert_has_no_errors(code, checks.check_greenthread_spawns)
@@ -18,6 +18,7 @@ import mock
from nova import exception from nova import exception
from nova.tests.unit.virt.hyperv import test_base from nova.tests.unit.virt.hyperv import test_base
from nova import utils
from nova.virt.hyperv import constants from nova.virt.hyperv import constants
from nova.virt.hyperv import eventhandler from nova.virt.hyperv import eventhandler
from nova.virt.hyperv import utilsfactory from nova.virt.hyperv import utilsfactory
@@ -103,7 +104,7 @@ class EventHandlerTestCase(test_base.HyperVBaseTestCase):
self._test_dispatch_event(missing_uuid=True) self._test_dispatch_event(missing_uuid=True)
@mock.patch.object(eventhandler.InstanceEventHandler, '_get_virt_event') @mock.patch.object(eventhandler.InstanceEventHandler, '_get_virt_event')
@mock.patch.object(eventlet, 'spawn_n') @mock.patch.object(utils, 'spawn_n')
def test_emit_event(self, mock_spawn, mock_get_event): def test_emit_event(self, mock_spawn, mock_get_event):
self._event_handler._emit_event(mock.sentinel.instance_name, self._event_handler._emit_event(mock.sentinel.instance_name,
mock.sentinel.instance_uuid, mock.sentinel.instance_uuid,
+5 -4
View File
@@ -25,6 +25,7 @@ from oslo_log import log as logging
from nova import exception from nova import exception
from nova.i18n import _LW from nova.i18n import _LW
from nova import utils
from nova.virt import event as virtevent from nova.virt import event as virtevent
from nova.virt.hyperv import constants from nova.virt.hyperv import constants
from nova.virt.hyperv import utilsfactory from nova.virt.hyperv import utilsfactory
@@ -71,7 +72,7 @@ class InstanceEventHandler(object):
self._running_state_callback = running_state_callback self._running_state_callback = running_state_callback
def start_listener(self): def start_listener(self):
eventlet.spawn_n(self._poll_events) utils.spawn_n(self._poll_events)
def _poll_events(self): def _poll_events(self):
while True: while True:
@@ -101,11 +102,11 @@ class InstanceEventHandler(object):
def _emit_event(self, instance_name, instance_uuid, instance_state): def _emit_event(self, instance_name, instance_uuid, instance_state):
virt_event = self._get_virt_event(instance_uuid, virt_event = self._get_virt_event(instance_uuid,
instance_state) instance_state)
eventlet.spawn_n(self._state_change_callback, virt_event) utils.spawn_n(self._state_change_callback, virt_event)
if instance_state == constants.HYPERV_VM_STATE_ENABLED: if instance_state == constants.HYPERV_VM_STATE_ENABLED:
eventlet.spawn_n(self._running_state_callback, utils.spawn_n(self._running_state_callback,
instance_name, instance_uuid) instance_name, instance_uuid)
def _get_instance_uuid(self, instance_name): def _get_instance_uuid(self, instance_name):
try: try:
+1 -2
View File
@@ -33,7 +33,6 @@ import socket
import sys import sys
import threading import threading
import eventlet
from eventlet import greenio from eventlet import greenio
from eventlet import greenthread from eventlet import greenthread
from eventlet import patcher from eventlet import patcher
@@ -457,7 +456,7 @@ class Host(object):
self._event_thread.start() self._event_thread.start()
LOG.debug("Starting green dispatch thread") LOG.debug("Starting green dispatch thread")
eventlet.spawn(self._dispatch_thread) utils.spawn(self._dispatch_thread)
def _get_new_connection(self): def _get_new_connection(self):
# call with _wrapped_conn_lock held # call with _wrapped_conn_lock held
+4 -3
View File
@@ -29,6 +29,7 @@ import webob
from nova.consoleauth import rpcapi as consoleauth_rpcapi from nova.consoleauth import rpcapi as consoleauth_rpcapi
from nova import context from nova import context
from nova.i18n import _LI from nova.i18n import _LI
from nova import utils
from nova import version from nova import version
from nova import wsgi from nova import wsgi
@@ -108,7 +109,7 @@ class XCPVNCProxy(object):
def proxy_connection(self, req, connect_info, start_response): def proxy_connection(self, req, connect_info, start_response):
"""Spawn bi-directional vnc proxy.""" """Spawn bi-directional vnc proxy."""
sockets = {} sockets = {}
t0 = eventlet.spawn(self.handshake, req, connect_info, sockets) t0 = utils.spawn(self.handshake, req, connect_info, sockets)
t0.wait() t0.wait()
if not sockets.get('client') or not sockets.get('server'): if not sockets.get('client') or not sockets.get('server'):
@@ -120,8 +121,8 @@ class XCPVNCProxy(object):
client = sockets['client'] client = sockets['client']
server = sockets['server'] server = sockets['server']
t1 = eventlet.spawn(self.one_way_proxy, client, server) t1 = utils.spawn(self.one_way_proxy, client, server)
t2 = eventlet.spawn(self.one_way_proxy, server, client) t2 = utils.spawn(self.one_way_proxy, server, client)
t1.wait() t1.wait()
t2.wait() t2.wait()
+2 -1
View File
@@ -39,6 +39,7 @@ import webob.exc
from nova import exception from nova import exception
from nova.i18n import _, _LE, _LI from nova.i18n import _, _LE, _LI
from nova import utils
wsgi_opts = [ wsgi_opts = [
cfg.StrOpt('api_paste_config', cfg.StrOpt('api_paste_config',
@@ -236,7 +237,7 @@ class Server(service.ServiceBase):
if self._max_url_len: if self._max_url_len:
wsgi_kwargs['url_length_limit'] = self._max_url_len wsgi_kwargs['url_length_limit'] = self._max_url_len
self._server = eventlet.spawn(**wsgi_kwargs) self._server = utils.spawn(**wsgi_kwargs)
def reset(self): def reset(self):
"""Reset server greenpool size to default. """Reset server greenpool size to default.