Browse Source

monkeypatch thread for keystoneclient

keystoneclient uses threading.Lock(), but swift doesn't
monkeypatch threading, this result in lockup when two
greenthreads try to acquire a non green lock.

This change fixes that.

Change-Id: I9b44284a5eb598a6978364819f253e031f4eaeef
Closes-bug: #1508424
tags/2.6.0
Mehdi Abaakouk 3 years ago
parent
commit
bf8689474a

+ 9
- 6
swift/common/utils.py View File

@@ -26,7 +26,6 @@ import os
26 26
 import pwd
27 27
 import re
28 28
 import sys
29
-import threading as stdlib_threading
30 29
 import time
31 30
 import uuid
32 31
 import functools
@@ -63,7 +62,6 @@ import six
63 62
 from six.moves import cPickle as pickle
64 63
 from six.moves.configparser import (ConfigParser, NoSectionError,
65 64
                                     NoOptionError, RawConfigParser)
66
-from six.moves.queue import Queue, Empty
67 65
 from six.moves import range
68 66
 from six.moves.urllib.parse import ParseResult
69 67
 from six.moves.urllib.parse import quote as _quote
@@ -74,6 +72,11 @@ import swift.common.exceptions
74 72
 from swift.common.http import is_success, is_redirection, HTTP_NOT_FOUND, \
75 73
     HTTP_PRECONDITION_FAILED, HTTP_REQUESTED_RANGE_NOT_SATISFIABLE
76 74
 
75
+if six.PY3:
76
+    stdlib_queue = eventlet.patcher.original('queue')
77
+else:
78
+    stdlib_queue = eventlet.patcher.original('Queue')
79
+stdlib_threading = eventlet.patcher.original('threading')
77 80
 
78 81
 # logging doesn't import patched as cleanly as one would like
79 82
 from logging.handlers import SysLogHandler
@@ -2333,7 +2336,7 @@ class GreenAsyncPile(object):
2333 2336
     def next(self):
2334 2337
         try:
2335 2338
             rv = self._responses.get_nowait()
2336
-        except Empty:
2339
+        except eventlet.queue.Empty:
2337 2340
             if self._inflight == 0:
2338 2341
                 raise StopIteration()
2339 2342
             rv = self._responses.get()
@@ -2984,8 +2987,8 @@ class ThreadPool(object):
2984 2987
 
2985 2988
     def __init__(self, nthreads=2):
2986 2989
         self.nthreads = nthreads
2987
-        self._run_queue = Queue()
2988
-        self._result_queue = Queue()
2990
+        self._run_queue = stdlib_queue.Queue()
2991
+        self._result_queue = stdlib_queue.Queue()
2989 2992
         self._threads = []
2990 2993
         self._alive = True
2991 2994
 
@@ -3065,7 +3068,7 @@ class ThreadPool(object):
3065 3068
             while True:
3066 3069
                 try:
3067 3070
                     ev, success, result = queue.get(block=False)
3068
-                except Empty:
3071
+                except stdlib_queue.Empty:
3069 3072
                     break
3070 3073
 
3071 3074
                 try:

+ 2
- 1
swift/common/wsgi.py View File

@@ -407,7 +407,8 @@ def run_server(conf, logger, sock, global_conf=None):
407 407
     wsgi.WRITE_TIMEOUT = int(conf.get('client_timeout') or 60)
408 408
 
409 409
     eventlet.hubs.use_hub(get_hub())
410
-    eventlet.patcher.monkey_patch(all=False, socket=True)
410
+    # NOTE(sileht): monkey-patching thread is required by python-keystoneclient
411
+    eventlet.patcher.monkey_patch(all=False, socket=True, thread=True)
411 412
     eventlet_debug = config_true_value(conf.get('eventlet_debug', 'no'))
412 413
     eventlet.debug.hub_exceptions(eventlet_debug)
413 414
     wsgi_logger = NullLogger()

+ 8
- 7
test/unit/common/middleware/test_ratelimit.py View File

@@ -18,7 +18,6 @@ import time
18 18
 import eventlet
19 19
 import mock
20 20
 from contextlib import contextmanager
21
-from threading import Thread
22 21
 
23 22
 from test.unit import FakeLogger
24 23
 from swift.common.middleware import ratelimit
@@ -28,6 +27,8 @@ from swift.common.memcached import MemcacheConnectionError
28 27
 from swift.common.swob import Request
29 28
 from swift.common import utils
30 29
 
30
+threading = eventlet.patcher.original('threading')
31
+
31 32
 
32 33
 class FakeMemcache(object):
33 34
 
@@ -313,10 +314,10 @@ class TestRateLimit(unittest.TestCase):
313 314
         req = Request.blank('/v/a/c')
314 315
         req.environ['swift.cache'] = FakeMemcache()
315 316
 
316
-        class rate_caller(Thread):
317
+        class rate_caller(threading.Thread):
317 318
 
318 319
             def __init__(self, parent):
319
-                Thread.__init__(self)
320
+                threading.Thread.__init__(self)
320 321
                 self.parent = parent
321 322
 
322 323
             def run(self):
@@ -356,10 +357,10 @@ class TestRateLimit(unittest.TestCase):
356 357
         req = Request.blank('/v/b/c')
357 358
         req.environ['swift.cache'] = FakeMemcache()
358 359
 
359
-        class rate_caller(Thread):
360
+        class rate_caller(threading.Thread):
360 361
 
361 362
             def __init__(self, parent):
362
-                Thread.__init__(self)
363
+                threading.Thread.__init__(self)
363 364
                 self.parent = parent
364 365
 
365 366
             def run(self):
@@ -505,11 +506,11 @@ class TestRateLimit(unittest.TestCase):
505 506
         req.method = 'PUT'
506 507
         req.environ = {}
507 508
 
508
-        class rate_caller(Thread):
509
+        class rate_caller(threading.Thread):
509 510
 
510 511
             def __init__(self, name):
511 512
                 self.myname = name
512
-                Thread.__init__(self)
513
+                threading.Thread.__init__(self)
513 514
 
514 515
             def run(self):
515 516
                 for j in range(num_calls):

+ 5
- 3
test/unit/common/test_manager.py View File

@@ -22,12 +22,14 @@ import resource
22 22
 import signal
23 23
 import errno
24 24
 from collections import defaultdict
25
-from threading import Thread
26 25
 from time import sleep, time
27 26
 
28 27
 from swift.common import manager
29 28
 from swift.common.exceptions import InvalidPidFileException
30 29
 
30
+import eventlet
31
+threading = eventlet.patcher.original('threading')
32
+
31 33
 DUMMY_SIG = 1
32 34
 
33 35
 
@@ -1153,9 +1155,9 @@ class TestServer(unittest.TestCase):
1153 1155
         server = manager.Server('test')
1154 1156
         self.assertEqual(server.wait(), 0)
1155 1157
 
1156
-        class MockProcess(Thread):
1158
+        class MockProcess(threading.Thread):
1157 1159
             def __init__(self, delay=0.1, fail_to_start=False):
1158
-                Thread.__init__(self)
1160
+                threading.Thread.__init__(self)
1159 1161
                 # setup pipe
1160 1162
                 rfd, wfd = os.pipe()
1161 1163
                 # subprocess connection to read stdout

+ 2
- 1
test/unit/common/test_utils.py View File

@@ -40,7 +40,6 @@ from six.moves import range
40 40
 from textwrap import dedent
41 41
 
42 42
 import tempfile
43
-import threading
44 43
 import time
45 44
 import traceback
46 45
 import unittest
@@ -64,6 +63,8 @@ from swift.common.container_sync_realms import ContainerSyncRealms
64 63
 from swift.common.swob import Request, Response, HeaderKeyDict
65 64
 from test.unit import FakeLogger
66 65
 
66
+threading = eventlet.patcher.original('threading')
67
+
67 68
 
68 69
 class MockOs(object):
69 70
 

+ 6
- 3
test/unit/common/test_wsgi.py View File

@@ -380,7 +380,8 @@ class TestWSGI(unittest.TestCase):
380 380
         self.assertEqual(30, _wsgi.WRITE_TIMEOUT)
381 381
         _eventlet.hubs.use_hub.assert_called_with(utils.get_hub())
382 382
         _eventlet.patcher.monkey_patch.assert_called_with(all=False,
383
-                                                          socket=True)
383
+                                                          socket=True,
384
+                                                          thread=True)
384 385
         _eventlet.debug.hub_exceptions.assert_called_with(False)
385 386
         self.assertTrue(_wsgi.server.called)
386 387
         args, kwargs = _wsgi.server.call_args
@@ -468,7 +469,8 @@ class TestWSGI(unittest.TestCase):
468 469
         self.assertEqual(30, _wsgi.WRITE_TIMEOUT)
469 470
         _eventlet.hubs.use_hub.assert_called_with(utils.get_hub())
470 471
         _eventlet.patcher.monkey_patch.assert_called_with(all=False,
471
-                                                          socket=True)
472
+                                                          socket=True,
473
+                                                          thread=True)
472 474
         _eventlet.debug.hub_exceptions.assert_called_with(False)
473 475
         self.assertTrue(_wsgi.server.called)
474 476
         args, kwargs = _wsgi.server.call_args
@@ -519,7 +521,8 @@ class TestWSGI(unittest.TestCase):
519 521
         self.assertEqual(30, _wsgi.WRITE_TIMEOUT)
520 522
         _eventlet.hubs.use_hub.assert_called_with(utils.get_hub())
521 523
         _eventlet.patcher.monkey_patch.assert_called_with(all=False,
522
-                                                          socket=True)
524
+                                                          socket=True,
525
+                                                          thread=True)
523 526
         _eventlet.debug.hub_exceptions.assert_called_with(True)
524 527
         self.assertTrue(mock_server.called)
525 528
         args, kwargs = mock_server.call_args

+ 3
- 1
test/unit/test_locale/test_locale.py View File

@@ -16,10 +16,12 @@
16 16
 # limitations under the License.
17 17
 
18 18
 from __future__ import print_function
19
+import eventlet
19 20
 import os
20 21
 import unittest
21 22
 import sys
22
-import threading
23
+
24
+threading = eventlet.patcher.original('threading')
23 25
 
24 26
 try:
25 27
     from subprocess import check_output

Loading…
Cancel
Save