def testWaitRaiseErrorAfterMarkFailure(self): if sys.version_info >= (3, 8) and platform.system() == 'Windows': # TODO(b/165013260): Fix this self.skipTest( 'Test is currently broken on Windows with Python 3.8') closure_queue = client._CoordinatedClosureQueue() closure_queue.put(self._create_closure( closure_queue._cancellation_mgr)) closure = closure_queue.get() wait_finish_event = threading.Event() coord = coordinator.Coordinator(clean_stop_exception_types=[]) # Using a thread to verify that closure_queue.wait() will not return until # all inflight closures are finished. def mark_finished_fn(): try: raise ValueError('Some error.') except ValueError as e: closure_queue.mark_failed(e) def wait_fn(): with self.assertRaises(ValueError): closure_queue.wait() self._assert_one_unblock_the_other(mark_finished_fn, wait_fn) self.assertTrue(closure_queue.done())
def testWaitRaiseErrorAfterMarkFailure(self): closure_queue = client._CoordinatedClosureQueue() closure_queue.put(self._create_closure( closure_queue._cancellation_mgr)) closure = closure_queue.get() wait_finish_event = threading.Event() coord = coordinator.Coordinator(clean_stop_exception_types=[]) # Using a thread to verify that closure_queue.wait() will not return until # all inflight closures are finished. def mark_finished_fn(): try: raise ValueError('Some error.') except ValueError as e: closure_queue.mark_failed(e) def wait_fn(): with self.assertRaises(ValueError): closure_queue.wait() self._assert_one_unblock_the_other(mark_finished_fn, wait_fn) self.assertTrue(closure_queue.done())
def testWaitRaiseErrorAfterMarkFailure(self): closure_queue = client._CoordinatedClosureQueue() closure_queue.put(self._create_closure()) closure = closure_queue.get() wait_finish_event = threading.Event() coord = coordinator.Coordinator(clean_stop_exception_types=[]) # Using a thread to verify that closure_queue.wait() will not return until # all inflight closures are finished. def mark_finished_fn(): with coord.stop_on_exception(): self.assertFalse(wait_finish_event.is_set()) try: raise ValueError('Some error.') except ValueError as e: closure_queue.mark_failed(e, closure) wait_finish_event.wait() t = threading.Thread(target=mark_finished_fn) t.start() with self.assertRaises(ValueError): closure_queue.wait() wait_finish_event.set() coord.join([t]) self.assertTrue(closure_queue.done())
def testBasic(self): queue = client._CoordinatedClosureQueue() closure1 = self._create_closure(queue._cancellation_mgr) queue.put(closure1) self.assertIs(closure1, queue.get()) self.assertFalse(queue.done()) queue.put_back(closure1) self.assertEqual(closure1, queue.get()) queue.mark_finished() self.assertTrue(queue.done()) queue.wait()
def _put_two_closures_and_get_one(self): closure_queue = client._CoordinatedClosureQueue() closure1 = self._create_closure(closure_queue._cancellation_mgr) closure_queue.put(closure1) closure2 = self._create_closure(closure_queue._cancellation_mgr) closure_queue.put(closure2) closure_got = closure_queue.get() # returns closure1 self.assertIs(closure_got, closure1) self.assertIsNot(closure_got, closure2) return closure_queue, closure1, closure2
def testProcessAtLeaseOnce(self): closure_queue = client._CoordinatedClosureQueue( MockCancellationManager()) labels = ['A', 'B', 'C', 'D', 'E'] processed_count = collections.defaultdict(int) coord = coordinator.Coordinator(clean_stop_exception_types=[]) def process_queue(): with coord.stop_on_exception(): has_been_put_back = False while True: closure = closure_queue.get(timeout=30) if closure is None: break if not has_been_put_back: has_been_put_back = True closure_queue.put_back(closure) continue closure._function() closure_queue.mark_finished() def get_func(label): def func(): logging.info('Label: %s, before waiting 3 sec', label) time.sleep(3) processed_count[label] += 1 logging.info('Label: %s, after waiting 3 sec', label) return func for label in labels: closure_queue.put( client.Closure(get_func(label), MockCancellationManager())) t1 = threading.Thread(target=process_queue, daemon=True) t1.start() t2 = threading.Thread(target=process_queue, daemon=True) t2.start() # Make sure multiple wait() calls are fine. closure_queue.wait() closure_queue.wait() closure_queue.wait() closure_queue.wait() self.assertEqual(processed_count, collections.Counter(labels)) coord.join([t1, t2])
def testNotifyBeforeWait(self): closure_queue = client._CoordinatedClosureQueue() def func(): logging.info('func running') coord = coordinator.Coordinator(clean_stop_exception_types=[]) def process_queue(): with coord.stop_on_exception(): closure = closure_queue.get() closure_queue.mark_finished(closure) closure_queue.put(client.Closure(func)) t = threading.Thread(target=process_queue) t.start() coord.join([t]) # This test asserts that waiting at the time the function has been processed # doesn't time out. closure_queue.wait()
def testThreadSafey(self): thread_count = 10 queue = client._CoordinatedClosureQueue() # Each thread performs 20 queue actions: 10 are `put_back` and 10 are # `mark_finished`. action_count = 20 def func(): for i in range(action_count): closure = queue.get() if i % 2 == 0: queue.put_back(closure) else: queue.mark_finished() threads = [threading.Thread(target=func) for i in range(thread_count)] for t in threads: t.start() for _ in range(thread_count * action_count // 2): queue.put(self._create_closure(queue._cancellation_mgr)) queue.wait() self.assertTrue(queue.done())