55 lines
1.8 KiB
Python
55 lines
1.8 KiB
Python
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):
|
|
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"]))
|