mirror of
https://github.com/python/cpython.git
synced 2025-10-09 08:31:26 +00:00
bpo-31699 Deadlocks in concurrent.futures.ProcessPoolExecutor
with pickling error (#3895)
Fix deadlocks in :class:`concurrent.futures.ProcessPoolExecutor` when task arguments or results cause pickling or unpickling errors. This should make sure that calls to the :class:`ProcessPoolExecutor` API always eventually return.
This commit is contained in:
parent
65f2a6dcc2
commit
94459fd7dc
5 changed files with 387 additions and 57 deletions
|
@ -1029,6 +1029,43 @@ class _TestQueue(BaseTestCase):
|
|||
self.assertTrue(q.get(timeout=1.0))
|
||||
close_queue(q)
|
||||
|
||||
def test_queue_feeder_on_queue_feeder_error(self):
|
||||
# bpo-30006: verify feeder handles exceptions using the
|
||||
# _on_queue_feeder_error hook.
|
||||
if self.TYPE != 'processes':
|
||||
self.skipTest('test not appropriate for {}'.format(self.TYPE))
|
||||
|
||||
class NotSerializable(object):
|
||||
"""Mock unserializable object"""
|
||||
def __init__(self):
|
||||
self.reduce_was_called = False
|
||||
self.on_queue_feeder_error_was_called = False
|
||||
|
||||
def __reduce__(self):
|
||||
self.reduce_was_called = True
|
||||
raise AttributeError
|
||||
|
||||
class SafeQueue(multiprocessing.queues.Queue):
|
||||
"""Queue with overloaded _on_queue_feeder_error hook"""
|
||||
@staticmethod
|
||||
def _on_queue_feeder_error(e, obj):
|
||||
if (isinstance(e, AttributeError) and
|
||||
isinstance(obj, NotSerializable)):
|
||||
obj.on_queue_feeder_error_was_called = True
|
||||
|
||||
not_serializable_obj = NotSerializable()
|
||||
# The captured_stderr reduces the noise in the test report
|
||||
with test.support.captured_stderr():
|
||||
q = SafeQueue(ctx=multiprocessing.get_context())
|
||||
q.put(not_serializable_obj)
|
||||
|
||||
# Verify that q is still functionning correctly
|
||||
q.put(True)
|
||||
self.assertTrue(q.get(timeout=1.0))
|
||||
|
||||
# Assert that the serialization and the hook have been called correctly
|
||||
self.assertTrue(not_serializable_obj.reduce_was_called)
|
||||
self.assertTrue(not_serializable_obj.on_queue_feeder_error_was_called)
|
||||
#
|
||||
#
|
||||
#
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue