""" Implement background services for the application. This is implemented as a cooperative concurrent task. """ from __future__ import absolute_import, print_function, division import functools class Service(object): def __init__(self, name="unnamed", arg=None): self.name = name self.enabled = True self.arg = arg self._task = self.process(self.arg) next(self._task) def service(self): """ Request for the service task. Servicing is disabled if it is disabled thourght the "enabled" attribute. When the task is executing, the service is disabled to avoid recursion. """ if self.enabled: enable = self.enabled try: # Prevent recursion self.enabled = False next(self._task) finally: self.enabled = enable def process(self, arg): """ Overrided to implement the service task. This must be a generator. Use `yield` to return control. """ raise NotImplementedError def __enter__(self): return self def __exit__(self, exc_type, exc_val, exc_tb): self.service() def after(self, fn): """ A decorator for a function. Service is triggered on return. """ @functools.wraps(fn) def wrap(*args, **kws): with self: return fn(*args, **kws) return wrap # ----------------------------------------------------------------------------- # The rest are for testing class HelloService(Service): def process(self, arg): count = 0 yield while True: print("Hello", count) count += 1 yield def test(): serv = HelloService("my.hello") print("1") serv.service() print("2") serv.service() with serv: print("3") @serv.after def nested(): print("4") nested() if __name__ == '__main__': test()