Events: use tpool only if thread module is patched
At the moment, we use eventlet.tpool when waiting for events even if the 'thread' module is not monkey patched, which causes locking issues. This patch changes this, checking if the 'thread' module is monkey patched, otherwise calling the method waiting for events directly. Related-Bug: #1568824 Change-Id: Ib752bfa2acc9f6b47996f6e949aadf20903c849b
This commit is contained in:
committed by
Claudiu Belu
parent
304fec7154
commit
356b6cca37
@@ -297,7 +297,8 @@ class ClusterUtilsTestCase(test_base.OsWinBaseTestCase):
|
||||
[self._clusterutils._LIVE_MIGRATION_TYPE])
|
||||
|
||||
@mock.patch.object(clusterutils, 'tpool')
|
||||
def test_monitor_vm_failover_no_vm(self, mock_tpool):
|
||||
@mock.patch.object(clusterutils, 'patcher')
|
||||
def test_monitor_vm_failover_no_vm(self, mock_patcher, mock_tpool):
|
||||
self._clusterutils._watcher = mock.MagicMock()
|
||||
fake_prev = mock.MagicMock(OwnerNode=self._FAKE_PREV_HOST)
|
||||
fake_wmi_object = mock.MagicMock(OwnerNode=self._FAKE_HOST,
|
||||
@@ -314,7 +315,8 @@ class ClusterUtilsTestCase(test_base.OsWinBaseTestCase):
|
||||
fake_callback.assert_not_called()
|
||||
|
||||
@mock.patch.object(clusterutils, 'tpool')
|
||||
def test_monitor_vm_failover(self, mock_tpool):
|
||||
@mock.patch.object(clusterutils, 'patcher')
|
||||
def test_monitor_vm_failover(self, mock_patcher, mock_tpool):
|
||||
self._clusterutils._watcher = mock.MagicMock()
|
||||
fake_prev = mock.MagicMock(OwnerNode=self._FAKE_PREV_HOST)
|
||||
fake_wmi_object = mock.MagicMock(OwnerNode=self._FAKE_HOST,
|
||||
|
||||
@@ -943,8 +943,9 @@ class VMUtilsTestCase(test_base.OsWinBaseTestCase):
|
||||
|
||||
@mock.patch('time.sleep')
|
||||
@mock.patch.object(vmutils, 'tpool')
|
||||
def test_vm_power_state_change_event_handler(self, mock_tpool,
|
||||
mock_sleep):
|
||||
@mock.patch.object(vmutils, 'patcher')
|
||||
def test_vm_power_state_change_event_handler(self, mock_patcher,
|
||||
mock_tpool, mock_sleep):
|
||||
self._mock_wmi.x_wmi_timed_out = exceptions.HyperVException
|
||||
|
||||
enabled_state = constants.HYPERV_VM_STATE_ENABLED
|
||||
|
||||
@@ -143,11 +143,12 @@ class NetworkUtilsTestCase(test_base.OsWinBaseTestCase):
|
||||
mock.sentinel.switch_port_name)
|
||||
self.assertEqual(mock.sentinel.mac_address, actual_mac_address)
|
||||
|
||||
@mock.patch.object(networkutils, 'patcher')
|
||||
@mock.patch.object(networkutils.tpool, 'execute')
|
||||
@mock.patch.object(networkutils, 'wmi', create=True)
|
||||
@mock.patch.object(networkutils.NetworkUtils, '_get_event_wql_query')
|
||||
def test_get_vnic_event_listener(self, mock_get_event_query, mock_wmi,
|
||||
mock_execute):
|
||||
mock_execute, mock_patcher):
|
||||
mock_wmi.x_wmi_timed_out = ValueError
|
||||
event = mock.MagicMock()
|
||||
port_class = self.netutils._conn.Msvm_SyntheticEthernetPortSettingData
|
||||
|
||||
@@ -23,6 +23,7 @@ import sys
|
||||
if sys.platform == 'win32':
|
||||
import wmi
|
||||
|
||||
from eventlet import patcher
|
||||
from eventlet import tpool
|
||||
from oslo_log import log as logging
|
||||
|
||||
@@ -211,8 +212,12 @@ class ClusterUtils(baseutils.BaseUtils):
|
||||
new_host = None
|
||||
try:
|
||||
# wait for new event for _WMI_EVENT_TIMEOUT_MS miliseconds.
|
||||
wmi_object = tpool.execute(self._watcher,
|
||||
self._WMI_EVENT_TIMEOUT_MS)
|
||||
if patcher.is_monkey_patched('thread'):
|
||||
wmi_object = tpool.execute(self._watcher,
|
||||
self._WMI_EVENT_TIMEOUT_MS)
|
||||
else:
|
||||
wmi_object = self._watcher(self._WMI_EVENT_TIMEOUT_MS)
|
||||
|
||||
old_host = wmi_object.previous.OwnerNode
|
||||
new_host = wmi_object.OwnerNode
|
||||
# wmi_object.Name field is of the form:
|
||||
|
||||
@@ -20,6 +20,7 @@ Based on the "root/virtualization/v2" namespace available starting with
|
||||
Hyper-V Server / Windows Server 2012.
|
||||
"""
|
||||
|
||||
import functools
|
||||
import sys
|
||||
import time
|
||||
import uuid
|
||||
@@ -27,6 +28,7 @@ import uuid
|
||||
if sys.platform == 'win32':
|
||||
import wmi
|
||||
|
||||
from eventlet import patcher
|
||||
from eventlet import tpool
|
||||
from oslo_config import cfg
|
||||
from oslo_log import log as logging
|
||||
@@ -818,16 +820,22 @@ class VMUtils(baseutils.BaseUtilsVirt):
|
||||
fields=[field])
|
||||
|
||||
def _handle_events(callback):
|
||||
if patcher.is_monkey_patched('thread'):
|
||||
# Retrieve one by one all the events that occurred in
|
||||
# the checked interval.
|
||||
#
|
||||
# We use eventlet.tpool for retrieving the events in
|
||||
# order to avoid issues caused by greenthread/thread
|
||||
# communication. Note that PyMI must use the unpatched
|
||||
# threading module.
|
||||
listen = functools.partial(tpool.execute, listener,
|
||||
event_timeout)
|
||||
else:
|
||||
listen = functools.partial(listener, event_timeout)
|
||||
|
||||
while True:
|
||||
try:
|
||||
# Retrieve one by one all the events that occurred in
|
||||
# the checked interval.
|
||||
#
|
||||
# We use eventlet.tpool for retrieving the events in
|
||||
# order to avoid issues caused by greenthread/thread
|
||||
# communication. Note that PyMI must use the unpatched
|
||||
# threading module.
|
||||
event = tpool.execute(listener, event_timeout)
|
||||
event = listen()
|
||||
|
||||
vm_name = event.ElementName
|
||||
vm_state = event.EnabledState
|
||||
|
||||
@@ -18,9 +18,11 @@ Utility class for network related operations.
|
||||
Based on the "root/virtualization/v2" namespace available starting with
|
||||
Hyper-V Server / Windows Server 2012.
|
||||
"""
|
||||
import functools
|
||||
import re
|
||||
|
||||
from eventlet import greenthread
|
||||
from eventlet import patcher
|
||||
from eventlet import tpool
|
||||
import sys
|
||||
|
||||
@@ -216,12 +218,18 @@ class NetworkUtils(baseutils.BaseUtilsVirt):
|
||||
query)
|
||||
|
||||
def _poll_events(callback):
|
||||
if patcher.is_monkey_patched('thread'):
|
||||
listen = functools.partial(tpool.execute, listener,
|
||||
self._VNIC_LISTENER_TIMEOUT_MS)
|
||||
else:
|
||||
listen = functools.partial(listener,
|
||||
self._VNIC_LISTENER_TIMEOUT_MS)
|
||||
|
||||
while True:
|
||||
# Retrieve one by one all the events that occurred in
|
||||
# the checked interval.
|
||||
try:
|
||||
event = tpool.execute(listener,
|
||||
self._VNIC_LISTENER_TIMEOUT_MS)
|
||||
event = listen()
|
||||
callback(event.ElementName)
|
||||
except wmi.x_wmi_timed_out:
|
||||
# no new event published.
|
||||
|
||||
Reference in New Issue
Block a user