def test_no_double_writers(self): lock = lock_utils.ReaderWriterLock() watch = timing.StopWatch(duration=5) watch.start() dups = collections.deque() active = collections.deque() def acquire_check(me): with lock.write_lock(): if len(active) >= 1: dups.append(me) dups.extend(active) active.append(me) try: time.sleep(random.random() / 100) finally: active.remove(me) def run(): me = threading.current_thread() while not watch.expired(): acquire_check(me) threads = [] for i in range(0, self.THREAD_COUNT): t = threading_utils.daemon_thread(run) threads.append(t) t.start() while threads: t = threads.pop() t.join() self.assertEqual([], list(dups)) self.assertEqual([], list(active))
def wait_for_workers(self, workers=1, timeout=None): """Waits for geq workers to notify they are ready to do work. NOTE(harlowja): if a timeout is provided this function will wait until that timeout expires, if the amount of workers does not reach the desired amount of workers before the timeout expires then this will return how many workers are still needed, otherwise it will return zero. """ if workers <= 0: raise ValueError("Worker amount must be greater than zero") w = None if timeout is not None: w = tt.StopWatch(timeout).start() self._workers_arrival.acquire() try: while len(self._workers_cache) < workers: if w is not None and w.expired(): return workers - len(self._workers_cache) timeout = None if w is not None: timeout = w.leftover() self._workers_arrival.wait(timeout) return 0 finally: self._workers_arrival.release()
def wait(self, timeout=None): # Wait until timeout expires (or forever) for jobs to appear. watch = None if timeout is not None: watch = tt.StopWatch(duration=float(timeout)).start() self._job_cond.acquire() try: while True: if not self._known_jobs: if watch is not None and watch.expired(): raise excp.NotFound("Expired waiting for jobs to" " arrive; waited %s seconds" % watch.elapsed()) # This is done since the given timeout can not be provided # to the condition variable, since we can not ensure that # when we acquire the condition that there will actually # be jobs (especially if we are spuriously awaken), so we # must recalculate the amount of time we really have left. timeout = None if watch is not None: timeout = watch.leftover() self._job_cond.wait(timeout) else: it = ZookeeperJobBoardIterator(self) it._jobs.extend(self._fetch_jobs()) it._fetched = True return it finally: self._job_cond.release()
def submit(self, fn, *args, **kwargs): watch = timing.StopWatch() if self._start_before_submit: watch.start() fut = self._submit_func(fn, *args, **kwargs) if not self._start_before_submit: watch.start() fut.add_done_callback(functools.partial(self._capture_stats, watch)) return fut
def test_backwards(self): watch = tt.StopWatch(0.1) watch.start() tt.StopWatch.advance_time_seconds(0.5) self.assertTrue(watch.expired()) tt.StopWatch.advance_time_seconds(-1.0) self.assertFalse(watch.expired()) self.assertEqual(0.0, watch.elapsed())
def submit(self, fn, *args, **kwargs): """Submit work to be executed and capture statistics.""" watch = timing.StopWatch() if self._start_before_submit: watch.start() fut = self._submit_func(fn, *args, **kwargs) if not self._start_before_submit: watch.start() fut.add_done_callback(functools.partial(self._capture_stats, watch)) return fut
def test_pause_resume(self): watch = tt.StopWatch() watch.start() tt.StopWatch.advance_time_seconds(0.05) watch.stop() elapsed = watch.elapsed() self.assertAlmostEqual(elapsed, watch.elapsed()) watch.resume() tt.StopWatch.advance_time_seconds(0.05) self.assertNotEqual(elapsed, watch.elapsed())
def _task_receiver(self, state, details): task_name = details['task_name'] if state == states.PENDING: self._timers.pop(task_name, None) elif state in STARTING_STATES: self._timers[task_name] = tt.StopWatch().start() elif state in FINISHED_STATES: timer = self._timers.pop(task_name, None) if timer is not None: timer.stop() self._record_ending(timer, task_name)
def _on_receive(content, message): LOG.debug("Submitting message '%s' for execution in the" " future to '%s'", ku.DelayedPretty(message), func_name) watch = tt.StopWatch() watch.start() try: self._executor.submit(_on_run, watch, content, message) except RuntimeError: LOG.error("Unable to continue processing message '%s'," " submission to instance executor (with later" " execution by '%s') was unsuccessful", ku.DelayedPretty(message), func_name, exc_info=True)
def _on_finish(self): sent_events = self._channel.sent_messages.get(_KIND_EVENT, 0) if sent_events: message = { 'created_on': timeutils.utcnow(), 'kind': _KIND_COMPLETE_ME, } if self._channel.put(message): watch = timing.StopWatch() watch.start() self._barrier.wait() LOG.blather("Waited %s seconds until task '%s' %s emitted" " notifications were depleted", watch.elapsed(), self._task, sent_events)
def __init__(self, task, uuid, action, arguments, timeout, **kwargs): self._task = task self._uuid = uuid self._action = action self._event = ACTION_TO_EVENT[action] self._arguments = arguments self._kwargs = kwargs self._watch = tt.StopWatch(duration=timeout).start() self._state = WAITING self._lock = threading.Lock() self._created_on = timeutils.utcnow() self._result = futures.Future() self._result.atom = task self._notifier = task.notifier
def __init__(self, task, uuid, action, arguments, progress_callback, timeout, **kwargs): self._task = task self._task_cls = reflection.get_class_name(task) self._uuid = uuid self._action = action self._event = ACTION_TO_EVENT[action] self._arguments = arguments self._progress_callback = progress_callback self._kwargs = kwargs self._watch = tt.StopWatch(duration=timeout).start() self._state = WAITING self._lock = threading.Lock() self._created_on = timeutils.utcnow() self.result = futures.Future()
def test_elapsed_maximum(self): watch = tt.StopWatch() watch.start() tt.StopWatch.advance_time_seconds(1) self.assertEqual(1, watch.elapsed()) tt.StopWatch.advance_time_seconds(10) self.assertEqual(11, watch.elapsed()) self.assertEqual(1, watch.elapsed(maximum=1)) watch.stop() self.assertEqual(11, watch.elapsed()) tt.StopWatch.advance_time_seconds(10) self.assertEqual(11, watch.elapsed()) self.assertEqual(0, watch.elapsed(maximum=-1))
def run(self, queue): watch = timing.StopWatch(duration=self._dispatch_periodicity) while (not self._dead.is_set() or (self._stop_when_empty and self._targets)): watch.restart() leftover = watch.leftover() while leftover: try: message = queue.get(timeout=leftover) except compat_queue.Empty: break else: self._dispatch(message) leftover = watch.leftover() leftover = watch.leftover() if leftover: self._dead.wait(leftover)
def wait(self, timeout=None): """Waits until the latch is released. NOTE(harlowja): if a timeout is provided this function will wait until that timeout expires, if the latch has been released before the timeout expires then this will return True, otherwise it will return False. """ watch = tt.StopWatch(duration=timeout) watch.start() with self._cond: while self._count > 0: if watch.expired(): return False else: self._cond.wait(watch.leftover(return_none=True)) return True
def wait(self, timeout=None): """Waits until the latch is released. :param timeout: wait until the timeout expires :type timeout: number :returns: true if the latch has been released before the timeout expires otherwise false :rtype: boolean """ watch = tt.StopWatch(duration=timeout) watch.start() with self._cond: while self._count > 0: if watch.expired(): return False else: self._cond.wait(watch.leftover(return_none=True)) return True
def on_conductor_event(cond, event, details): print('Event \'%s\' has been received...' % event) print('Details = %s' % details) if event.endswith('_start'): w = timing.StopWatch() w.start() base_event = event[0:-len('_start')] event_watches[base_event] = w if event.endswith('_end'): base_event = event[0:-len('_end')] try: w = event_watches.pop(base_event) w.stop() print('It took %0.3f seconds for event \'%s\' to finish' % (w.elapsed(), base_event)) except KeyError: pass if event == 'running_end': cond.stop()
def wait_for_workers(self, workers=1, timeout=None): """Waits for geq workers to notify they are ready to do work. NOTE(harlowja): if a timeout is provided this function will wait until that timeout expires, if the amount of workers does not reach the desired amount of workers before the timeout expires then this will return how many workers are still needed, otherwise it will return zero. """ if workers <= 0: raise ValueError("Worker amount must be greater than zero") watch = tt.StopWatch(duration=timeout) watch.start() with self._cond: while self._total_workers() < workers: if watch.expired(): return max(0, workers - self._total_workers()) self._cond.wait(watch.leftover(return_none=True)) return 0
def on_conductor_event(cond, event, details): print("Event '%s' has been received..." % event) print("Details = %s" % details) if event.endswith("_start"): w = timing.StopWatch() w.start() base_event = event[0:-len("_start")] event_watches[base_event] = w if event.endswith("_end"): base_event = event[0:-len("_end")] try: w = event_watches.pop(base_event) w.stop() print("It took %0.3f seconds for event '%s' to finish" % (w.elapsed(), base_event)) except KeyError: pass if event == 'running_end' and only_run_once: cond.stop()
def test_no_concurrent_readers_writers(self): lock = lock_utils.ReaderWriterLock() watch = timing.StopWatch(duration=5) watch.start() dups = collections.deque() active = collections.deque() def acquire_check(me, reader): if reader: lock_func = lock.read_lock else: lock_func = lock.write_lock with lock_func(): if not reader: # There should be no-one else currently active, if there # is ensure we capture them so that we can later blow-up # the test. if len(active) >= 1: dups.append(me) dups.extend(active) active.append(me) try: time.sleep(random.random() / 100) finally: active.remove(me) def run(): me = threading.current_thread() while not watch.expired(): acquire_check(me, random.choice([True, False])) threads = [] for i in range(0, self.THREAD_COUNT): t = threading_utils.daemon_thread(run) threads.append(t) t.start() while threads: t = threads.pop() t.join() self.assertEqual([], list(dups)) self.assertEqual([], list(active))
def wait(self, timeout=None): """Waits until the latch is released. NOTE(harlowja): if a timeout is provided this function will wait until that timeout expires, if the latch has been released before the timeout expires then this will return True, otherwise it will return False. """ w = None if timeout is not None: w = tt.StopWatch(timeout).start() with self._cond: while self._count > 0: if w is not None: if w.expired(): return False else: timeout = w.leftover() self._cond.wait(timeout) return True
def test_splits(self): watch = tt.StopWatch() watch.start() self.assertEqual(0, len(watch.splits)) watch.split() self.assertEqual(1, len(watch.splits)) self.assertEqual(watch.splits[0].elapsed, watch.splits[0].length) tt.StopWatch.advance_time_seconds(0.05) watch.split() splits = watch.splits self.assertEqual(2, len(splits)) self.assertNotEqual(splits[0].elapsed, splits[1].elapsed) self.assertEqual(splits[1].length, splits[1].elapsed - splits[0].elapsed) watch.stop() self.assertEqual(2, len(watch.splits)) watch.start() self.assertEqual(0, len(watch.splits))
def test_not_expired(self): watch = tt.StopWatch(0.1) watch.start() tt.StopWatch.advance_time_seconds(0.05) self.assertFalse(watch.expired())
def test_no_states(self): watch = tt.StopWatch() self.assertRaises(RuntimeError, watch.stop) self.assertRaises(RuntimeError, watch.resume)
def test_expiry(self): watch = tt.StopWatch(0.1) watch.start() tt.StopWatch.advance_time_seconds(0.2) self.assertTrue(watch.expired())
def test_no_expiry(self): watch = tt.StopWatch(0.1) self.assertRaises(RuntimeError, watch.expired)
def test_elapsed(self): watch = tt.StopWatch() watch.start() tt.StopWatch.advance_time_seconds(0.2) # NOTE(harlowja): Allow for a slight variation by using 0.19. self.assertGreaterEqual(0.19, watch.elapsed())
def test_context_manager(self): with tt.StopWatch() as watch: tt.StopWatch.advance_time_seconds(0.05) self.assertGreater(0.01, watch.elapsed())
def test_no_elapsed(self): watch = tt.StopWatch() self.assertRaises(RuntimeError, watch.elapsed)
def test_no_leftover(self): watch = tt.StopWatch() self.assertRaises(RuntimeError, watch.leftover) watch = tt.StopWatch(1) self.assertRaises(RuntimeError, watch.leftover)