import sched,time,string,json from threading import Thread from sys import exit class TaskPool: def __init__(self,**kwargs): self.base_state = kwargs self.base_state["task_pool"] = self self.scheduler = sched.scheduler(time.time,time.sleep) self.thread = Thread(target=self.worker,args=(self,)) self.coroutines = [] self.states = {} self.killswitch = False def periodical(self,scheduler,interval,action,index,state=dict()): if self.killswitch: return self.states[index] = action(state,self.base_state) if not self.killswitch: scheduler.enter(interval,1,self.periodical,(scheduler,interval,action,index,self.states[index])) def worker(self,tasks): for c,coro in enumerate(tasks.coroutines): interval = coro["interval"] action = coro["action"] state = coro.get("state",dict()) tasks.periodical(tasks.scheduler,interval,action,c,state) tasks.scheduler.run() exit(0) def run(self): if self.thread.is_alive(): return # don't set up an already set-up thread self.thread.daemon = True self.thread.start() def stop(self): list(map(self.scheduler.cancel, self.scheduler.queue)) self.killswitch = True # kill any lingering tasks def add_coroutine(self,action,interval,state=dict(),name=None): if name is None: name = string.ascii_letters[len(self.coroutines)] self.coroutines.append(dict(action=action,interval=interval,state=state,name=name)) def save_state(self, index): with open("state.{}.json".format(self.coroutines[index]["name"]),"w") as f: json.dump(self.states[index],f) def load_state(self, index): try: with open("state.{}.json".format(self.coroutines[index]["name"])) as f: self.states[index] = json.load(f) self.coroutines[index]["state"] = self.states[index] except: print("state.{}.json not found or couldn't be opened; using default".format(self.coroutines[index]["name"]))