def do_test_for_change(self, watcher, path): st = monotonic() while monotonic() - st < 1: if watcher(path): return sleep(0.1) self.fail('The change to {0} was not detected'.format(path))
def run(thread_shutdown_event=None, pl_shutdown_event=None, pl_config_loader=None, interval=None): powerline = Powerline( 'wm', renderer_module='pango_markup', shutdown_event=pl_shutdown_event, config_loader=pl_config_loader, ) powerline.update_renderer() if not thread_shutdown_event: thread_shutdown_event = powerline.shutdown_event while not thread_shutdown_event.is_set(): # powerline.update_interval may change over time used_interval = interval or powerline.update_interval start_time = monotonic() s = powerline.render(side='right') request = 'powerline_widget:set_markup(\'' + s.translate({ '\'': '\\\'', '\\': '\\\\' }) + '\')\n' client = Popen(['awesome-client'], shell=False, stdout=PIPE, stderr=PIPE, stdin=PIPE) client.stdin.write(request.encode('utf-8')) client.stdin.close() read_to_log(powerline.pl, client) thread_shutdown_event.wait( max(used_interval - (monotonic() - start_time), 0.1))
def run(self): while not self.shutdown_event.is_set(): start_time = monotonic() try: self.update_value = self.update(self.update_value) except Exception as e: self.exception('Exception while updating: {0}', str(e)) self.skip = True except KeyboardInterrupt: self.warn('Caught keyboard interrupt while updating') self.skip = True else: self.skip = False self.shutdown_event.wait(max(self.interval - (monotonic() - start_time), self.min_sleep_time))
def run(self): if self.do_update_first: start_time = monotonic() while True: self.shutdown_event.wait(max(self.interval - (monotonic() - start_time), self.min_sleep_time)) if self.shutdown_event.is_set(): break start_time = monotonic() self.set_update_value() else: while not self.shutdown_event.is_set(): start_time = monotonic() self.set_update_value() self.shutdown_event.wait(max(self.interval - (monotonic() - start_time), self.min_sleep_time))
def do_branch_rename_test(self, repo, q): st = monotonic() while monotonic() - st < 1: # Give inotify time to deliver events ans = repo.branch() if hasattr(q, '__call__'): if q(ans): break else: if ans == q: break sleep(0.01) if hasattr(q, '__call__'): self.assertTrue(q(ans)) else: self.assertEqual(ans, q)
def expire_old_queries(self): pop = [] now = monotonic() for path, lt in self.last_query_times.items(): if now - lt > self.expire_time: pop.append(path) for path in pop: del self.last_query_times[path]
def compute_state(self, interface): if interface == 'detect': proc_exists = getattr(self, 'proc_exists', None) if proc_exists is None: proc_exists = self.proc_exists = os.path.exists( '/proc/net/route') if proc_exists: # Look for default interface in routing table with open('/proc/net/route', 'rb') as f: for line in f.readlines(): parts = line.split() if len(parts) > 1: iface, destination = parts[:2] if not destination.replace(b'0', b''): interface = iface.decode('utf-8') break if interface == 'detect': # Choose interface with most total activity, excluding some # well known interface names interface, total = 'eth0', -1 for name, rx, tx in _get_interfaces(): base = self.replace_num_pat.match(name) if None in (base, rx, tx) or base.group() in ('lo', 'vmnet', 'sit'): continue activity = rx + tx if activity > total: total = activity interface = name try: idata = self.interfaces[interface] try: idata['prev'] = idata['last'] except KeyError: pass except KeyError: idata = {} if self.run_once: idata['prev'] = (monotonic(), _get_bytes(interface)) self.shutdown_event.wait(self.interval) self.interfaces[interface] = idata idata['last'] = (monotonic(), _get_bytes(interface)) return idata.copy()
def update_one(self, crashed, updates, key): try: updates[key] = (monotonic(), self.compute_state(key)) except Exception as e: self.exception('Exception while computing state for {0!r}: {1}', key, str(e)) crashed.add(key) except KeyboardInterrupt: self.warn('Interrupt while computing state for {0!r}', key) crashed.add(key)
def run(self): if self.do_update_first: start_time = monotonic() while True: self.shutdown_event.wait( max(self.interval - (monotonic() - start_time), self.min_sleep_time)) if self.shutdown_event.is_set(): break start_time = monotonic() self.set_update_value() else: while not self.shutdown_event.is_set(): start_time = monotonic() self.set_update_value() self.shutdown_event.wait( max(self.interval - (monotonic() - start_time), self.min_sleep_time))
def compute_state(self, interface): if interface == "detect": proc_exists = getattr(self, "proc_exists", None) if proc_exists is None: proc_exists = self.proc_exists = os.path.exists("/proc/net/route") if proc_exists: # Look for default interface in routing table with open("/proc/net/route", "rb") as f: for line in f.readlines(): parts = line.split() if len(parts) > 1: iface, destination = parts[:2] if not destination.replace(b"0", b""): interface = iface.decode("utf-8") break if interface == "detect": # Choose interface with most total activity, excluding some # well known interface names interface, total = "eth0", -1 for name, rx, tx in _get_interfaces(): base = self.replace_num_pat.match(name) if None in (base, rx, tx) or base.group() in ("lo", "vmnet", "sit"): continue activity = rx + tx if activity > total: total = activity interface = name try: idata = self.interfaces[interface] try: idata["prev"] = idata["last"] except KeyError: pass except KeyError: idata = {} if self.run_once: idata["prev"] = (monotonic(), _get_bytes(interface)) self.shutdown_event.wait(self.interval) self.interfaces[interface] = idata idata["last"] = (monotonic(), _get_bytes(interface)) return idata.copy()
def decorated_function(**kwargs): if self.cache_reg_func: self.cache_reg_func(self.cache) self.cache_reg_func = None key = self.cache_key(**kwargs) try: cached = self.cache.get(key, None) except TypeError: return func(**kwargs) # Handle case when time() appears to be less then cached['time'] due # to clock updates. Not applicable for monotonic clock, but this # case is currently rare. if cached is None or not (cached['time'] < monotonic() < cached['time'] + self.timeout): cached = self.cache[key] = { 'result': func(**kwargs), 'time': monotonic(), } return cached['result']
def compute_state(self, interface): if interface == 'detect': proc_exists = getattr(self, 'proc_exists', None) if proc_exists is None: proc_exists = self.proc_exists = os.path.exists('/proc/net/route') if proc_exists: # Look for default interface in routing table with open('/proc/net/route', 'rb') as f: for line in f.readlines(): parts = line.split() if len(parts) > 1: iface, destination = parts[:2] if not destination.replace(b'0', b''): interface = iface.decode('utf-8') break if interface == 'detect': # Choose interface with most total activity, excluding some # well known interface names interface, total = 'eth0', -1 for name, rx, tx in _get_interfaces(): base = self.replace_num_pat.match(name) if None in (base, rx, tx) or base.group() in ('lo', 'vmnet', 'sit'): continue activity = rx + tx if activity > total: total = activity interface = name if interface in self.interfaces: idata = self.interfaces[interface] try: idata['prev'] = idata['last'] except KeyError: pass else: idata = {} if self.run_once: idata['prev'] = (monotonic(), _get_bytes(interface)) self.shutdown_event.wait(self.interval) self.interfaces[interface] = idata idata['last'] = (monotonic(), _get_bytes(interface)) return idata
def render(self, update_value, update_first, **kwargs): queries, crashed = update_value key = self.key(**kwargs) if key in crashed: return self.crashed_value try: update_state = queries[key][1] except KeyError: # Allow only to forbid to compute missing values: in either user # configuration or in subclasses. update_state = self.compute_state(key) if ((update_first and self.update_first) or self.run_once) else None with self.write_lock: self.new_queries[key] = (monotonic(), update_state) return self.render_one(update_state, **kwargs)
def __call__(self, path, logger=None): path = os.path.abspath(path) self.expire_old_queries() self.last_query_times[path] = monotonic() w = self.watches.get(path, None) if w is None: try: self.watch(path) except NoSuchDir: pass return True try: return w() except DirTooLarge as e: if logger is not None: logger.warn(str(e)) self.watches[path] = DummyTreeWatcher(path) return False
def __call__(self, path, ignore_event=None): path = realpath(path) self.expire_old_queries() self.last_query_times[path] = monotonic() w = self.watches.get(path, None) if w is None: try: self.watch(path, ignore_event=ignore_event) except NoSuchDir: pass return True try: return w() except BaseDirChanged: self.watches.pop(path, None) return True except DirTooLarge as e: self.pl.warn(str(e)) self.watches[path] = DummyTreeWatcher(path) return False
def update(self, old_update_value): updates = {} crashed = set() update_value = (updates, crashed) queries = old_update_value[0] new_queries = self.new_queries with self.write_lock: self.new_queries = [] for key, (last_query_time, state) in queries.items(): if last_query_time < monotonic() < last_query_time + self.interval: updates[key] = (last_query_time, state) else: self.update_one(crashed, updates, key) for key in new_queries: self.update_one(crashed, updates, key) return update_value
def __call__(self, path): ''' Return True if path has been modified since the last call. Can raise OSError if the path does not exist. ''' path = realpath(path) with self.lock: self.last_query[path] = monotonic() self.expire_watches() if path not in self.watches: # Try to re-add the watch, it will fail if the file does not # exist/you don't have permission self.watch(path) return True self.read(get_name=False) if path not in self.modified: # An ignored event was received which means the path has been # automatically unwatched return True ans = self.modified[path] if ans: self.modified[path] = False return ans
def __call__(self, path): ''' Return True if path has been modified since the last call. Can raise OSError if the path does not exist. ''' path = self.os.path.abspath(path) with self.lock: self.last_query[path] = monotonic() self.expire_watches() if path not in self.watches: # Try to re-add the watch, it will fail if the file does not # exist/you dont have permission self.watch(path) return True self.read(get_name=False) if path not in self.modified: # An ignored event was received which means the path has been # automatically unwatched return True ans = self.modified[path] if ans: self.modified[path] = False return ans
def update(self, old_update_value): updates = {} crashed = set() update_value = (updates, crashed) queries = old_update_value[0] with self.write_lock: if self.new_queries: queries.update(self.new_queries) self.new_queries.clear() for key, (last_query_time, state) in queries.items(): if last_query_time < monotonic() < last_query_time + self.drop_interval: try: updates[key] = (last_query_time, self.compute_state(key)) except Exception as e: self.exception('Exception while computing state for {0!r}: {1}', key, str(e)) crashed.add(key) except KeyboardInterrupt: self.warn('Interrupt while computing state for {0!r}', key) crashed.add(key) return update_value
def expire_watches(self): now = monotonic() for path, last_query in tuple(self.last_query.items()): if last_query - now > self.expire_time: self.unwatch(path)
if __name__ == '__main__': name = 'wm' if len(sys.argv) > 1: name = sys.argv[1] powerline = I3Powerline(name, renderer_module='i3bar') powerline.update_renderer() interval = 0.5 print('{"version": 1}') print('[') print('[]') lock = Lock() def render(event=None, data=None, sub=None): global lock with lock: print(',[' + powerline.render()[:-1] + ']') sys.stdout.flush() i3 = get_i3_connection() i3_subscribe(i3, 'workspace', render) while True: start_time = monotonic() render() time.sleep(max(interval - (monotonic() - start_time), 0.1))
def test_threaded_segment(self): log = [] pl = Pl() updates = [(None,)] lock = threading.Lock() event = threading.Event() block_event = threading.Event() class TestSegment(ThreadedSegment): interval = 10 def set_state(self, **kwargs): event.clear() log.append(('set_state', kwargs)) return super(TestSegment, self).set_state(**kwargs) def update(self, update_value): block_event.wait() event.set() # Make sleep first to prevent some race conditions log.append(('update', update_value)) with lock: ret = updates[0] if isinstance(ret, Exception): raise ret else: return ret[0] def render(self, update, **kwargs): log.append(('render', update, kwargs)) if isinstance(update, Exception): raise update else: return update # Non-threaded tests segment = TestSegment() block_event.set() updates[0] = (None,) self.assertEqual(segment(pl=pl), None) self.assertEqual(thread_number(), 1) self.assertEqual(log, [ ('set_state', {}), ('update', None), ('render', None, {'pl': pl, 'update_first': True}), ]) log[:] = () segment = TestSegment() block_event.set() updates[0] = ('abc',) self.assertEqual(segment(pl=pl), 'abc') self.assertEqual(thread_number(), 1) self.assertEqual(log, [ ('set_state', {}), ('update', None), ('render', 'abc', {'pl': pl, 'update_first': True}), ]) log[:] = () segment = TestSegment() block_event.set() updates[0] = ('abc',) self.assertEqual(segment(pl=pl, update_first=False), 'abc') self.assertEqual(thread_number(), 1) self.assertEqual(log, [ ('set_state', {}), ('update', None), ('render', 'abc', {'pl': pl, 'update_first': False}), ]) log[:] = () segment = TestSegment() block_event.set() updates[0] = ValueError('abc') self.assertEqual(segment(pl=pl), None) self.assertEqual(thread_number(), 1) self.assertEqual(len(pl.exceptions), 1) self.assertEqual(log, [ ('set_state', {}), ('update', None), ]) log[:] = () pl.exceptions[:] = () segment = TestSegment() block_event.set() updates[0] = (TypeError('def'),) self.assertRaises(TypeError, segment, pl=pl) self.assertEqual(thread_number(), 1) self.assertEqual(log, [ ('set_state', {}), ('update', None), ('render', updates[0][0], {'pl': pl, 'update_first': True}), ]) log[:] = () # Threaded tests segment = TestSegment() block_event.clear() kwargs = {'pl': pl, 'update_first': False, 'other': 1} with lock: updates[0] = ('abc',) segment.startup(**kwargs) ret = segment(**kwargs) self.assertEqual(thread_number(), 2) block_event.set() event.wait() segment.shutdown_event.set() segment.thread.join() self.assertEqual(ret, None) self.assertEqual(log, [ ('set_state', {'update_first': False, 'other': 1}), ('render', None, {'pl': pl, 'update_first': False, 'other': 1}), ('update', None), ]) log[:] = () segment = TestSegment() block_event.set() kwargs = {'pl': pl, 'update_first': True, 'other': 1} with lock: updates[0] = ('def',) segment.startup(**kwargs) ret = segment(**kwargs) self.assertEqual(thread_number(), 2) segment.shutdown_event.set() segment.thread.join() self.assertEqual(ret, 'def') self.assertEqual(log, [ ('set_state', {'update_first': True, 'other': 1}), ('update', None), ('render', 'def', {'pl': pl, 'update_first': True, 'other': 1}), ]) log[:] = () segment = TestSegment() block_event.set() kwargs = {'pl': pl, 'update_first': True, 'interval': 0.2} with lock: updates[0] = ('abc',) segment.startup(**kwargs) start = monotonic() ret1 = segment(**kwargs) with lock: updates[0] = ('def',) self.assertEqual(thread_number(), 2) sleep(0.5) ret2 = segment(**kwargs) segment.shutdown_event.set() segment.thread.join() end = monotonic() duration = end - start self.assertEqual(ret1, 'abc') self.assertEqual(ret2, 'def') self.assertEqual(log[:5], [ ('set_state', {'update_first': True, 'interval': 0.2}), ('update', None), ('render', 'abc', {'pl': pl, 'update_first': True, 'interval': 0.2}), ('update', 'abc'), ('update', 'def'), ]) num_runs = len([e for e in log if e[0] == 'update']) self.assertAlmostEqual(duration / 0.2, num_runs, delta=1) log[:] = () segment = TestSegment() block_event.set() kwargs = {'pl': pl, 'update_first': True, 'interval': 0.2} with lock: updates[0] = ('ghi',) segment.startup(**kwargs) start = monotonic() ret1 = segment(**kwargs) with lock: updates[0] = TypeError('jkl') self.assertEqual(thread_number(), 2) sleep(0.5) ret2 = segment(**kwargs) segment.shutdown_event.set() segment.thread.join() end = monotonic() duration = end - start self.assertEqual(ret1, 'ghi') self.assertEqual(ret2, None) self.assertEqual(log[:5], [ ('set_state', {'update_first': True, 'interval': 0.2}), ('update', None), ('render', 'ghi', {'pl': pl, 'update_first': True, 'interval': 0.2}), ('update', 'ghi'), ('update', 'ghi'), ]) num_runs = len([e for e in log if e[0] == 'update']) self.assertAlmostEqual(duration / 0.2, num_runs, delta=1) self.assertEqual(num_runs - 1, len(pl.exceptions)) log[:] = ()
def test_threaded_segment(self): log = [] pl = Pl() updates = [(None, )] lock = threading.Lock() event = threading.Event() block_event = threading.Event() class TestSegment(ThreadedSegment): interval = 10 def set_state(self, **kwargs): event.clear() log.append(('set_state', kwargs)) return super(TestSegment, self).set_state(**kwargs) def update(self, update_value): block_event.wait() event.set() # Make sleep first to prevent some race conditions log.append(('update', update_value)) with lock: ret = updates[0] if isinstance(ret, Exception): raise ret else: return ret[0] def render(self, update, **kwargs): log.append(('render', update, kwargs)) if isinstance(update, Exception): raise update else: return update # Non-threaded tests segment = TestSegment() block_event.set() updates[0] = (None, ) self.assertEqual(segment(pl=pl), None) self.assertEqual(thread_number(), 1) self.assertEqual(log, [ ('set_state', {}), ('update', None), ('render', None, { 'pl': pl, 'update_first': True }), ]) log[:] = () segment = TestSegment() block_event.set() updates[0] = ('abc', ) self.assertEqual(segment(pl=pl), 'abc') self.assertEqual(thread_number(), 1) self.assertEqual(log, [ ('set_state', {}), ('update', None), ('render', 'abc', { 'pl': pl, 'update_first': True }), ]) log[:] = () segment = TestSegment() block_event.set() updates[0] = ('abc', ) self.assertEqual(segment(pl=pl, update_first=False), 'abc') self.assertEqual(thread_number(), 1) self.assertEqual(log, [ ('set_state', {}), ('update', None), ('render', 'abc', { 'pl': pl, 'update_first': False }), ]) log[:] = () segment = TestSegment() block_event.set() updates[0] = ValueError('abc') self.assertEqual(segment(pl=pl), None) self.assertEqual(thread_number(), 1) self.assertEqual(len(pl.exceptions), 1) self.assertEqual(log, [ ('set_state', {}), ('update', None), ]) log[:] = () pl.exceptions[:] = () segment = TestSegment() block_event.set() updates[0] = (TypeError('def'), ) self.assertRaises(TypeError, segment, pl=pl) self.assertEqual(thread_number(), 1) self.assertEqual(log, [ ('set_state', {}), ('update', None), ('render', updates[0][0], { 'pl': pl, 'update_first': True }), ]) log[:] = () # Threaded tests segment = TestSegment() block_event.clear() kwargs = {'pl': pl, 'update_first': False, 'other': 1} with lock: updates[0] = ('abc', ) segment.startup(**kwargs) ret = segment(**kwargs) self.assertEqual(thread_number(), 2) block_event.set() event.wait() segment.shutdown_event.set() segment.thread.join() self.assertEqual(ret, None) self.assertEqual(log, [ ('set_state', { 'update_first': False, 'other': 1 }), ('render', None, { 'pl': pl, 'update_first': False, 'other': 1 }), ('update', None), ]) log[:] = () segment = TestSegment() block_event.set() kwargs = {'pl': pl, 'update_first': True, 'other': 1} with lock: updates[0] = ('def', ) segment.startup(**kwargs) ret = segment(**kwargs) self.assertEqual(thread_number(), 2) segment.shutdown_event.set() segment.thread.join() self.assertEqual(ret, 'def') self.assertEqual(log, [ ('set_state', { 'update_first': True, 'other': 1 }), ('update', None), ('render', 'def', { 'pl': pl, 'update_first': True, 'other': 1 }), ]) log[:] = () segment = TestSegment() block_event.set() kwargs = {'pl': pl, 'update_first': True, 'interval': 0.2} with lock: updates[0] = ('abc', ) segment.startup(**kwargs) start = monotonic() ret1 = segment(**kwargs) with lock: updates[0] = ('def', ) self.assertEqual(thread_number(), 2) sleep(0.5) ret2 = segment(**kwargs) segment.shutdown_event.set() segment.thread.join() end = monotonic() duration = end - start self.assertEqual(ret1, 'abc') self.assertEqual(ret2, 'def') self.assertEqual(log[:5], [ ('set_state', { 'update_first': True, 'interval': 0.2 }), ('update', None), ('render', 'abc', { 'pl': pl, 'update_first': True, 'interval': 0.2 }), ('update', 'abc'), ('update', 'def'), ]) num_runs = len([e for e in log if e[0] == 'update']) self.assertAlmostEqual(duration / 0.2, num_runs, delta=1) log[:] = () segment = TestSegment() block_event.set() kwargs = {'pl': pl, 'update_first': True, 'interval': 0.2} with lock: updates[0] = ('ghi', ) segment.startup(**kwargs) start = monotonic() ret1 = segment(**kwargs) with lock: updates[0] = TypeError('jkl') self.assertEqual(thread_number(), 2) sleep(0.5) ret2 = segment(**kwargs) segment.shutdown_event.set() segment.thread.join() end = monotonic() duration = end - start self.assertEqual(ret1, 'ghi') self.assertEqual(ret2, None) self.assertEqual(log[:5], [ ('set_state', { 'update_first': True, 'interval': 0.2 }), ('update', None), ('render', 'ghi', { 'pl': pl, 'update_first': True, 'interval': 0.2 }), ('update', 'ghi'), ('update', 'ghi'), ]) num_runs = len([e for e in log if e[0] == 'update']) self.assertAlmostEqual(duration / 0.2, num_runs, delta=1) self.assertEqual(num_runs - 1, len(pl.exceptions)) log[:] = ()
from threading import Lock name = 'wm' if len( sys.argv ) > 1: name = sys.argv[1] powerline = Powerline(name, renderer_module='i3bgbar') powerline.update_renderer() interval = 0.5 print( '{"version": 1, "custom_workspace": true}' ) print( '[' ) print( ' [[],[]]' ) lock = Lock() def render( event=None, data=None, sub=None ): global lock with lock: s = '[\n' + powerline.render(side='right')[:-2] + '\n]\n' s += ',[\n' + powerline.render(side='left' )[:-2] + '\n]' print( ',[\n' + s + '\n]' ) sys.stdout.flush() sub = i3.Subscription( render, 'workspace' ) while True: start_time = monotonic() render() time.sleep(max(interval - (monotonic() - start_time), 0.1))