our_knp/fly-knp/worker.py

29 lines
1.4 KiB
Python

from pathlib import Path
import subprocess,threading,queue,json,time,atexit
R=Path.home()/'run/fly-knp'
class Worker:
def __init__(self,mode='cpu'):self.mode=mode;self.p=None;atexit.register(self.close)
def close(self):
p=self.p;self.p=None
if p:
p.terminate()
try:p.wait(timeout=2)
except subprocess.TimeoutExpired:p.kill();p.wait()
def start(self):
self.close();self.q=queue.Queue();q=self.q;p=subprocess.Popen([str(R/'controller'),self.mode],stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.STDOUT,text=True,bufsize=1);self.p=p
def read():
with (R/('worker-'+self.mode+'.log')).open('a') as log:
for line in p.stdout:
if line.startswith('RESULT '):q.put(json.loads(line[7:]))
else:log.write(line);log.flush()
q.put(None)
threading.Thread(target=read,daemon=True).start()
def infer(self,sensors):
if not isinstance(sensors,list) or len(sensors)!=9 or any(type(v) is not int or not 0<=v<=15 for v in sensors):raise ValueError('Nine integer sensors0..15 required')
if self.p is None or self.p.poll() is not None:self.start()
t=time.monotonic()
try:
self.p.stdin.write(' '.join(map(str,sensors))+'\n');self.p.stdin.flush();v=self.q.get(timeout=20)
if v is None:raise RuntimeError('KNP worker stopped')
return dict(v,backend='KNP '+self.mode,neuralMilliseconds=round((time.monotonic()-t)*1000,3))
except Exception:self.close();raise