1# -*- coding: utf-8 -*- 2""" 3Utilities for lazy resolution of configurations. 4 5Provides a bunch of tools to perform actions that need 6the configuration to be in place when performed 7 8""" 9 10from logging import getLogger 11log = getLogger(__name__) 12 13 14class _ConfigMilestoneTracker(object): 15 """Tracks actions that need to be performed 16 when a specific configuration point is reached 17 and required options are correctly initialized 18 19 """ 20 def __init__(self, name): 21 self.name = name 22 self._actions = dict() 23 self._reached = False 24 self._keep_on_reset = [] 25 26 @property 27 def reached(self): 28 return self._reached 29 30 def register(self, action, persist_on_reset=False): 31 """Registers an action to be called on milestone completion. 32 33 If milestone is already passed action is immediately called 34 35 """ 36 if persist_on_reset: 37 self._keep_on_reset.append(action) 38 39 if self._reached: 40 log.debug('%s milestone passed, calling %s directly', self.name, action) 41 action() 42 else: 43 log.debug('Register %s to be called when %s reached', action, self.name) 44 self._actions[id(action)] = action 45 46 def reach(self): 47 """Marks the milestone as reached. 48 49 Runs the registered actions. Calling this 50 method multiple times should lead to nothing. 51 52 """ 53 log.debug('%s milestone reached', self.name) 54 55 try: 56 while True: 57 try: 58 __, action = self._actions.popitem() 59 action() 60 except KeyError: 61 break 62 finally: 63 self._reached = True 64 65 def _reset(self): 66 """This is just for testing purposes""" 67 self._reached = False 68 self._actions = dict() 69 for action in self._keep_on_reset: 70 self.register(action) 71 72 73config_ready = _ConfigMilestoneTracker('config_ready') 74renderers_ready = _ConfigMilestoneTracker('renderers_ready') 75environment_loaded = _ConfigMilestoneTracker('environment_loaded') 76 77 78def _reset_all(): 79 """Utility method for the test suite to reset milestones""" 80 config_ready._reset() 81 renderers_ready._reset() 82 environment_loaded._reset() 83 84 85def _reach_all(): 86 """Utility method for the test suite to reach all milestones""" 87 config_ready.reach() 88 renderers_ready.reach() 89 environment_loaded.reach() 90