def stop(self, grace): """See base.End.stop for specification.""" with self._lock: if self._cycle is None: event = threading.Event() event.set() return event elif not self._cycle.operations: event = threading.Event() self._cycle.pool.submit(event.set) self._cycle.pool.shutdown(wait=False) self._cycle = None return event else: self._cycle.grace = True event = threading.Event() self._cycle.idle_actions.append(event.set) if 0 < grace: future = later.later( grace, _future_shutdown(self._lock, self._cycle, event)) self._cycle.futures.append(future) else: _abort(self._cycle.operations.values()) return event
def test_callback(self): lock = threading.Lock() cell = [0] callback_called = [False] future_passed_to_callback = [None] def computation(): with lock: cell[0] += 1 computation_future = later.later(TICK * 2, computation) def callback(outcome): with lock: callback_called[0] = True future_passed_to_callback[0] = outcome computation_future.add_done_callback(callback) time.sleep(TICK) with lock: self.assertFalse(callback_called[0]) time.sleep(TICK * 2) with lock: self.assertTrue(callback_called[0]) self.assertTrue(future_passed_to_callback[0].done()) callback_called[0] = False future_passed_to_callback[0] = None computation_future.add_done_callback(callback) with lock: self.assertTrue(callback_called[0]) self.assertTrue(future_passed_to_callback[0].done())
def test_result(self): lock = threading.Lock() cell = [0] callback_called = [False] future_passed_to_callback_cell = [None] return_value = object() def computation(): with lock: cell[0] += 1 return return_value computation_future = later.later(TICK * 2, computation) def callback(future_passed_to_callback): with lock: callback_called[0] = True future_passed_to_callback_cell[0] = future_passed_to_callback computation_future.add_done_callback(callback) returned_value = computation_future.result() self.assertEqual(return_value, returned_value) # The callback may not yet have been called! Sleep a tick. time.sleep(TICK) with lock: self.assertTrue(callback_called[0]) self.assertEqual(return_value, future_passed_to_callback_cell[0].result())
def test_simple_delay(self): lock = threading.Lock() cell = [0] return_value = object() def computation(): with lock: cell[0] += 1 return return_value computation_future = later.later(TICK * 2, computation) self.assertFalse(computation_future.done()) self.assertFalse(computation_future.cancelled()) time.sleep(TICK) self.assertFalse(computation_future.done()) self.assertFalse(computation_future.cancelled()) with lock: self.assertEqual(0, cell[0]) time.sleep(TICK * 2) self.assertTrue(computation_future.done()) self.assertFalse(computation_future.cancelled()) with lock: self.assertEqual(1, cell[0]) self.assertEqual(return_value, computation_future.result())
def change_timeout(self, timeout): if self._future is not None and timeout != self._timeout: self._future.cancel() new_timeout = min(timeout, self._maximum_timeout) new_index = self._index + 1 self._timeout = new_timeout self._deadline = self._commencement + new_timeout self._index = new_index delay = self._deadline - time.time() self._future = later.later(delay, lambda: self._expire(new_index))
def change_timeout(self, timeout): if self._future is not None and timeout != self._timeout: self._future.cancel() new_timeout = min(timeout, self._maximum_timeout) new_index = self._index + 1 self._timeout = new_timeout self._deadline = self._commencement + new_timeout self._index = new_index delay = self._deadline - time.time() self._future = later.later( delay, lambda: self._expire(new_index))
def start(self): self._index = 0 self._future = later.later(self._timeout, self._expire(0))