import time from datetime import datetime class renderer(object): """Base class for something that can render.""" def render(self): pass class abstaining_renderer(renderer): """A renderer that doesn't do it all the time.""" def __init__(self, name_to_timeout_dict): self.name_to_timeout_dict = name_to_timeout_dict; self.last_runs = {} for key in name_to_timeout_dict: self.last_runs[key] = 0 def should_render(self, keys_to_skip): now = time.time() for key in self.name_to_timeout_dict: if key in keys_to_skip: continue if (now - self.last_runs[key]) > self.name_to_timeout_dict[key]: return key return None def render(self): tries = {} keys_to_skip = set() while True: key = self.should_render(keys_to_skip) if key == None: break if key in tries: tries[key] += 1 else: tries[key] = 0 if tries[key] > 5: print(('Too many retries for "%s.%s", giving up for now' % ( key, self.__class__))) keys_to_skip.add(key) else: msg = 'renderer: periodic render event for "%s.%s"' % ( key, self.__class__) if (tries[key] > 1): msg = msg + " (try %d)" % tries[key] print(msg) if (self.periodic_render(key)): self.last_runs[key] = time.time() def periodic_render(self, key): pass class debuggable_abstaining_renderer(abstaining_renderer): def __init__(self, name_to_timeout_dict, debug): super(debuggable_abstaining_renderer, self).__init__(name_to_timeout_dict); self.debug = debug def debug_prefix(self): return "none" def being_debugged(self): return self.debug def debug_print(self, template, *args): try: if self.being_debugged(): if args: msg = template.format(args) else: msg = template # current date and time now = datetime.now() timestamp = now.strftime("%d-%b-%Y (%H:%M:%S.%f)") print("%s(%s): %s" % (self.debug_prefix(), timestamp, msg)) except Exception as e: print("Exception in debug_print!") print(e)