Exception in callback AsyncIOScheduler.wakeup - python

After adding jobs to an AsyncIOScheduler, it appears the first time it tries to execute the schedule I get Exceptions.
I have a Kasa Smart Plug which I am trying to control using a Qt app. I can turn in on/off but when trying to turn it on/off using the AsyncIOScheduler, it will attempt to run the jobs but I get an error. I was having trouble submitting the jobs to the scheduler but I have gotten past that. I'm at a loss of what is going on.
qtest.py
import sys
import asyncio
#from PyQt5.QtCore import *
#from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from asyncqt import QEventLoop, asyncSlot
from MyPlug import MyPlug
from apscheduler.schedulers.background import BackgroundScheduler
import time
from datetime import datetime
import os
from datetime import datetime
from apscheduler.schedulers.asyncio import AsyncIOScheduler
from time import sleep
from apscheduler.schedulers.qt import QtScheduler
class Form(QDialog):
loop = None
scheduler = None
def __init__(self, loop=None):
super(Form, self).__init__()
self.loop = asyncio.get_event_loop()
self.scheduler = AsyncIOScheduler(job_defaults={'misfire_grace_time': 5})
#self.scheduler = BackgroundScheduler()
scheduler = self.scheduler
layout = QVBoxLayout()
self.setLayout(layout)
self.uon_name = "Upper On"
self.uoff_name = "Upper Off"
self.lon_name = "Lower On"
self.loff_name = "Lower Off"
self.sched_name = "Schedule"
self.quit_name = "Quit"
# Upper On
self.up_on = QPushButton("Upper On")
self.up_on.clicked.connect(lambda:self.whichbtn(self.up_on))
# Upper Off
self.up_off = QPushButton("Upper Off")
self.up_off.clicked.connect(lambda:self.whichbtn(self.up_off))
# Lower On
self.lo_on = QPushButton("Lower On")
self.lo_on.clicked.connect(lambda:self.whichbtn(self.lo_on))
# Lower Off
self.lo_off = QPushButton("Lower Off")
self.lo_off.clicked.connect(lambda:self.whichbtn(self.lo_off))
# Schedule
self.sched = QPushButton("Schedule")
self.sched.clicked.connect(lambda:self.whichbtn(self.sched))
#Quit
self.quit = QPushButton(self.quit_name)
self.quit.clicked.connect(lambda:self.quit_app())
layout.addWidget(self.up_on)
layout.addWidget(self.up_off)
layout.addWidget(self.lo_on)
layout.addWidget(self.lo_off)
layout.addWidget(self.quit)
layout.addWidget(self.sched)
self.setWindowTitle("Outlet Demo")
self.mp = MyPlug("10.0.0.31")
#asyncSlot()
async def whichbtn(self, btn):
if btn.text() == "Upper On":
print("Upper On")
await self.mp.turn_on(0)
if btn.text() =="Upper Off" :
print("Upper Off")
await self.mp.turn_off(0)
if btn.text() == "Lower On":
print("Lower On")
await self.mp.turn_on(1)
if btn.text() == "Lower Off":
print("Lower Off")
await self.mp.turn_off(1)
if btn.text() == "Schedule":
print("Schedule")
await self.mp.sched_on(self.scheduler)
await self.mp.sched_off(self.scheduler)
self.scheduler.start()
print(self.scheduler)
print(self.scheduler.get_jobs())
def sched_me(self):
print("A scheduled job ", datetime.now().strftime("%H:%M:%S"))
def quit_app(self):
print("quit_app")
self.loop.stop()
print("Loop running ", self.loop.is_running())
self.loop.close()
print("Loop closed ", self.loop.is_closed())
self.close()
def main():
app = QApplication(sys.argv)
loop = QEventLoop(app)
asyncio.set_event_loop(loop)
ex = Form(loop)
ex.show()
with loop:
loop.run_forever()
if __name__ == '__main__':
main()
`
MyPlug.py
from kasa import SmartStrip
class MyPlug(SmartStrip):
def __init__(self, ip_address):
super().__init__(ip_address)
async def initialize(self, child):
await self.update()
async def turn_on(self, child):
print('turn on')
await self.update()
await self.children[child].turn_on()
async def turn_off(self, child):
print('turn off')
await self.update()
await self.children[child].turn_off()
async def sched_on(self, sched):
print("schedule turn on start")
sched.add_job(MyPlug.turn_on, 'interval', seconds=3, args=[self, 0])
print("schedule turn on done")
async def sched_off(self, sched):
print("schedule turn off start")
sched.add_job(MyPlug.turn_off, 'interval', seconds=7, args=[self, 0])
print("schedule turn off done")
import sys
import asyncio
#from PyQt5.QtCore import *
#from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from asyncqt import QEventLoop, asyncSlot
from MyPlug import MyPlug
from apscheduler.schedulers.background import BackgroundScheduler
import time
from datetime import datetime
import os
from datetime import datetime
from apscheduler.schedulers.asyncio import AsyncIOScheduler
from time import sleep
from apscheduler.schedulers.qt import QtScheduler
class Form(QDialog):
loop = None
scheduler = None
def __init__(self, loop=None):
super(Form, self).__init__()
self.loop = asyncio.get_event_loop()
self.scheduler = AsyncIOScheduler(job_defaults={'misfire_grace_time': 5})
#self.scheduler = BackgroundScheduler()
scheduler = self.scheduler
layout = QVBoxLayout()
self.setLayout(layout)
self.uon_name = "Upper On"
self.uoff_name = "Upper Off"
self.lon_name = "Lower On"
self.loff_name = "Lower Off"
self.sched_name = "Schedule"
self.quit_name = "Quit"
# Upper On
self.up_on = QPushButton("Upper On")
self.up_on.clicked.connect(lambda:self.whichbtn(self.up_on))
# Upper Off
self.up_off = QPushButton("Upper Off")
self.up_off.clicked.connect(lambda:self.whichbtn(self.up_off))
# Lower On
self.lo_on = QPushButton("Lower On")
self.lo_on.clicked.connect(lambda:self.whichbtn(self.lo_on))
# Lower Off
self.lo_off = QPushButton("Lower Off")
self.lo_off.clicked.connect(lambda:self.whichbtn(self.lo_off))
# Schedule
self.sched = QPushButton("Schedule")
self.sched.clicked.connect(lambda:self.whichbtn(self.sched))
#Quit
self.quit = QPushButton(self.quit_name)
self.quit.clicked.connect(lambda:self.quit_app())
layout.addWidget(self.up_on)
layout.addWidget(self.up_off)
layout.addWidget(self.lo_on)
layout.addWidget(self.lo_off)
layout.addWidget(self.quit)
layout.addWidget(self.sched)
self.setWindowTitle("Outlet Demo")
self.mp = MyPlug("10.0.0.31")
#asyncSlot()
async def whichbtn(self, btn):
if btn.text() == "Upper On":
print("Upper On")
await self.mp.turn_on(0)
if btn.text() =="Upper Off" :
print("Upper Off")
await self.mp.turn_off(0)
if btn.text() == "Lower On":
print("Lower On")
await self.mp.turn_on(1)
if btn.text() == "Lower Off":
print("Lower Off")
await self.mp.turn_off(1)
if btn.text() == "Schedule":
print("Schedule")
await self.mp.sched_on(self.scheduler)
await self.mp.sched_off(self.scheduler)
self.scheduler.start()
print(self.scheduler)
print(self.scheduler.get_jobs())
def sched_me(self):
print("A scheduled job ", datetime.now().strftime("%H:%M:%S"))
def quit_app(self):
print("quit_app")
self.loop.stop()
print("Loop running ", self.loop.is_running())
self.loop.close()
print("Loop closed ", self.loop.is_closed())
self.close()
def main():
app = QApplication(sys.argv)
loop = QEventLoop(app)
asyncio.set_event_loop(loop)
ex = Form(loop)
ex.show()
with loop:
loop.run_forever()
if __name__ == '__main__':
main()
Running qtest and selecting the schedule button, I get the following:
python qtest.py
Schedule
schedule turn on start
schedule turn on done
schedule turn off start
schedule turn off done
<apscheduler.schedulers.asyncio.AsyncIOScheduler object at 0x7fdc3c5a79a0>
[<Job (id=fc672c91bd16492aacd21833ce744d06 name=MyPlug.turn_on)>, <Job (id=c4f01284a2664ddcb810ad542a3de39b name=MyPlug.turn_off)>]
Exception in callback AsyncIOScheduler.wakeup(<apscheduler....x7fdc3c5a79a0>)() at /home/mike/.local/lib/python3.10/site-packages/apscheduler/schedulers/asyncio.py:58
handle: <Handle AsyncIOScheduler.wakeup(<apscheduler....x7fdc3c5a79a0>)() at /home/mike/.local/lib/python3.10/site-packages/apscheduler/schedulers/asyncio.py:58>
Traceback (most recent call last):
File "/usr/lib64/python3.10/asyncio/events.py", line 80, in _run
self._context.run(self._callback, *self._args)
File "/home/mike/.local/lib/python3.10/site-packages/apscheduler/schedulers/asyncio.py", line 62, in wakeup
self._start_timer(wait_seconds)
File "/home/mike/.local/lib/python3.10/site-packages/apscheduler/schedulers/asyncio.py", line 51, in _start_timer
self._timeout = self._eventloop.call_later(wait_seconds, self.wakeup)
File "/home/mike/.local/lib/python3.10/site-packages/asyncqt/__init__.py", line 364, in call_later
return self._add_callback(asyncio.Handle(callback, args, self, context=context), delay)
File "/home/mike/.local/lib/python3.10/site-packages/asyncqt/__init__.py", line 368, in _add_callback
return self._timer.add_callback(handle, delay)
File "/home/mike/.local/lib/python3.10/site-packages/asyncqt/__init__.py", line 202, in add_callback
timerid = self.startTimer(delay * 1000)
TypeError: startTimer(self, int, timerType: Qt.TimerType = Qt.CoarseTimer): argument 1 has unexpected type 'float'
Any help is appreciated

Related

Stop asyncio task, that was started inside a function in a class

I try to cancel a specific asyncio task that was started in a function inside a class.
But it doesn't work. The task starts up again....
Thanks for some inspirations! :)
def button_stop_command():
t1.cancel()
#check which tasks are running
tasks = asyncio.all_tasks()
for task in tasks:
print(f'> {task.get_name()}, {task.get_coro()}')
class ZMQHandler():
def __init__(self):
self.loop = asyncio.get_event_loop()
url= 'tcp://192.168.0.91:28332'
channel= 'sequence'
self.ctx = zmq.asyncio.Context.instance()
self.sock = self.ctx.socket(zmq.SUB)
self.sock.connect(url)
self.sock.setsockopt(zmq.SUBSCRIBE, channel.encode())
print("Open ZMQ socket on", ZMQ_URL)
async def handle(self) :
[..code...]
asyncio.ensure_future(self.handle())
def start(self):
global t1
self.loop.add_signal_handler(signal.SIGINT, self.stop)
t1=self.loop.create_task(self.handle())
self.loop.run_forever()
async def tk_main(root):
while True:
root.update()
await asyncio.sleep(0.05)
tkmain = asyncio.ensure_future(tk_main(root))
daemon = ZMQHandler()
daemon.start()
I want to cancel a specific task
Everytime I post something, I get a new idea, and then the problem gets solved. My idea was:
def button_stop_command():
t1.cancel()
#check which tasks are running
tasks = asyncio.all_tasks()
for task in tasks:
print(f'> {task.get_name()}, {task.get_coro()}')
class ZMQHandler():
def __init__(self):
self.loop = asyncio.get_event_loop()
url= 'tcp://192.168.0.91:28332'
channel= 'sequence'
self.ctx = zmq.asyncio.Context.instance()
self.sock = self.ctx.socket(zmq.SUB)
self.sock.connect(url)
self.sock.setsockopt(zmq.SUBSCRIBE, channel.encode())
print("Open ZMQ socket on", ZMQ_URL)
async def handle(self) :
global t1
[..code...]
t1= asyncio.ensure_future(self.handle())
def start(self):
self.loop.add_signal_handler(signal.SIGINT, self.stop)
self.loop.create_task(self.handle())
self.loop.run_forever()
async def tk_main(root):
while True:
root.update()
await asyncio.sleep(0.05)
tkmain = asyncio.ensure_future(tk_main(root))
daemon = ZMQHandler()
daemon.start()

How do I check if the ProcessPoolExecutor is full?

We want to know if the executor has reached max_workers. Is there a simple way to find out how many workers are running in the following code?
import concurrent.futures
def dummy_process(arg_a, arg_b):
print("ml_process", arg_a, arg_b)
time.sleep(5)
executor = concurrent.futures.ProcessPoolExecutor(max_workers=2)
def main():
while True:
executor.submit(dummy_process, "test_a", "test_b")
if __name__ == "__main__":
main()
use try except
import concurrent.futures
def dummy_process(arg_a, arg_b):
print("ml_process", arg_a, arg_b)
time.sleep(5)
executor = concurrent.futures.ProcessPoolExecutor(max_workers=2)
def main():
while True:
try:
executor.submit(dummy_process, "test_a", "test_b")
except:
print("Pool Executer is Full")
if __name__ == "__main__":
main()

Threaded application does not stop with keyboard interrupt Python

I want to stop the threaded python application with keyboard interrupt. One thread captures the images and put them in queue and the other thread saves the images to hardisk.
The code is here
import numpy as np
import threading
import time
from multiprocessing import Queue
import cv2
from datetime import datetime
import os
#import matplotlib.pyplot as plt
import sys
frames = Queue(50)
exitProgram = False
saveImages = True
class ImageGrabber(threading.Thread):
def __init__(self, ID):
threading.Thread.__init__(self)
self.ID=ID
self.cam=cv2.VideoCapture(ID)
self.fps = self.cam.get(cv2.CAP_PROP_FPS)
self.w=self.cam.get(cv2.CAP_PROP_FRAME_WIDTH)
self.h=self.cam.get(cv2.CAP_PROP_FRAME_HEIGHT)
(self.grabbed, self.frame) =self.cam.read()
cv2.imwrite("testImage.png",self.frame)
print(f"Camera Opened with fps {self.fps}, width = {self.w}, and height = {self.h}")
self.stopped = False
# self.adjustB = adjustBrightness(0.75)
def run(self):
global frames
global exitProgram
while not self.stopped:
if not self.grabbed or exitProgram is True:
print("Exit Command reached")
self.stop()
self.cam.release()
else:
(self.grabbed, self.frame) =self.cam.read()
frames.put(self.frame)
def stop(self):
self.stopped = True
class imageSaveThread(threading.Thread):
def __init__(self,grabber,filePath):
threading.Thread.__init__(self)
global saveImages
self.dateTime = self.getDateStamp()
self.imgName = filePath + 'img_' + self.dateTime + '_'
self.cntr = 0
def getDateStamp(self):
filedate = str(datetime.now())
filedate = filedate[0:-7]
filedate = filedate.replace(':', '_')
filename = filedate
return filename
def run(self):
global frames
while True:
if(not frames.empty()):
self.Currframe=frames.get()
cv2.imwrite(self.imgName + str(self.cntr).zfill(6) + '.png',self.Currframe)
self.cntr = self.cntr + 1
print(f"Queue Size in writing = {frames.qsize()} and fram number = {self.cntr}")
elif exitProgram is True:
print("Exit Command imageSaveThread reached")
print(f"Final Queue Size at exit = {frames.qsize()}")
break
def main():
if saveImages == True:
savefilePath = 'D:/111/'
grabber = ImageGrabber(0)
imageSaveThr = imageSaveThread(grabber,savefilePath)
grabber.start()
imageSaveThr.start()
e = threading.Event()
# imageSaveThread.join()
# grabber.join()
print ('Press CTRL-C to interrupt')
while grabber.isAlive():
try:
time.sleep(5) #wait 1 second, then go back and ask if thread is still alive
except KeyboardInterrupt: #if ctrl-C is pressed within that second,
#catch the KeyboardInterrupt exception
e.set() #set the flag that will kill the thread when it has finished
exitProgram=True
print ('Exiting...')
grabber.join()
imageSaveThr.join()
else:
videoCodec = 'h264'
videoExt = 'mkv'
if __name__ == '__main__':
main()
I I replace the main function and directly call the program then it works and exits the threads like the code below
import numpy as np
import threading
import time
from multiprocessing import Queue
import cv2
from datetime import datetime
import os
#import matplotlib.pyplot as plt
import sys
frames = Queue(50)
exitProgram = False
saveImages = True
class ImageGrabber(threading.Thread):
def __init__(self, ID):
threading.Thread.__init__(self)
self.ID=ID
self.cam=cv2.VideoCapture(ID)
self.fps = self.cam.get(cv2.CAP_PROP_FPS)
self.w=self.cam.get(cv2.CAP_PROP_FRAME_WIDTH)
self.h=self.cam.get(cv2.CAP_PROP_FRAME_HEIGHT)
(self.grabbed, self.frame) =self.cam.read()
cv2.imwrite("testImage.png",self.frame)
print(f"Camera Opened with fps {self.fps}, width = {self.w}, and height = {self.h}")
self.stopped = False
# self.adjustB = adjustBrightness(0.75)
def run(self):
global frames
global exitProgram
while not self.stopped:
if not self.grabbed or exitProgram is True:
print("Exit Command reached")
self.stop()
self.cam.release()
else:
(self.grabbed, self.frame) =self.cam.read()
frames.put(self.frame)
def stop(self):
self.stopped = True
class imageSaveThread(threading.Thread):
def __init__(self,grabber,filePath):
threading.Thread.__init__(self)
global saveImages
self.dateTime = self.getDateStamp()
self.imgName = filePath + 'img_' + self.dateTime + '_'
self.cntr = 0
def getDateStamp(self):
filedate = str(datetime.now())
filedate = filedate[0:-7]
filedate = filedate.replace(':', '_')
filename = filedate
return filename
def run(self):
global frames
while True:
if(not frames.empty()):
self.Currframe=frames.get()
cv2.imwrite(self.imgName + str(self.cntr).zfill(6) + '.png',self.Currframe)
self.cntr = self.cntr + 1
print(f"Queue Size in writing = {frames.qsize()} and fram number = {self.cntr}")
elif exitProgram is True:
print("Exit Command imageSaveThread reached")
print(f"Final Queue Size at exit = {frames.qsize()}")
break
savefilePath = 'D:/111/'
grabber = ImageGrabber(0)
imageSaveThr = imageSaveThread(grabber,savefilePath)
grabber.start()
imageSaveThr.start()
e = threading.Event()
# imageSaveThread.join()
# grabber.join()
print ('Press CTRL-C to interrupt')
while grabber.isAlive():
try:
time.sleep(5) #wait 1 second, then go back and ask if thread is still alive
except KeyboardInterrupt: #if ctrl-C is pressed within that second,
#catch the KeyboardInterrupt exception
e.set() #set the flag that will kill the thread when it has finished
exitProgram=True
print ('Exiting...')
grabber.join()
imageSaveThr.join()
I am not able to understand the reason. Can anyone tell me what is the reason?
PS(Would've added this as an comment, but I can't since I don't meet the requirements)
I'll leave the explanation to somebody else, since I was not able to get your code running on my computer.
But have you looked at adding an sys.exit(0) at the end of your except block? It made a difference for me whenever I tried to use KeyboarInterrupt to get out of this little code snippet:
import sys
if __name__ == "__main__":
while True:
try:
print("Hello")
except KeyboardInterrupt:
print("Exiting...")
sys.exit(0)
PS: Use Ctrl+Z and kill the process manually if you end up removing the sys.exit() part.

close a while loop to start another in pyqt5 with button clicked in python and asyncio

i am trying to wrote a python script who start a thread with asyncio after clicked button1 and after another clicked button2 it s close the thread1 and start another loop with different parameters.
this is a way that i would like to do but the thread1 wont stop when create thread2...
could you help me please?
import os
import sys
import quamash
import asyncio
import traceback
import PyQt5
import pdb
import math
# Required setup to get event loop working
app = PyQt5.QtWidgets.QApplication(sys.argv)
loop = quamash.QEventLoop(app)
asyncio.set_event_loop(loop)
loop.set_debug(True) # optional
# Select QT5
# https://github.com/enthought/traitsui/issues/407
os.environ["ETS_TOOLKIT"] = "qt"
os.environ["QT_API"] = "pyqt5"
from traits.api import HasTraits, Button, Instance, Int, Bool
from traitsui.api import ModelView, View, Item, Label
from PyQt5.QtCore import pyqtRemoveInputHook
pyqtRemoveInputHook() # enabled pdb.set_trace() ????
class App(HasTraits):
""" Traits application model.
"""
running = Bool(False)
async def test_task(self):
while True:
loop = asyncio.get_event_loop()
self.running = True
print("oooooooooooook") #commande pour faire actioer position et retour indfo console
await asyncio.sleep(0.02, loop)
self.running = False
running = Bool(False)
async def test_task2(self):
while True:
loop = asyncio.get_event_loop()
self.running = True
print("ko") #commande pour faire actioer position et retour indfo console
await asyncio.sleep(0.02, loop)
self.running = False
class AppView(ModelView):
""" Traits application view.
"""
model = Instance(App)
test_task_btn = Button("START1")
test_task_btn2 = Button("STOP1andSTART2")
def close(self, info, is_ok):
print("Close")
return True
def _test_task_btn_fired(self):
print("Button pressed.")
try:
loop.close
loop.create_task(self.model.test_task())
except:
traceback.print_exc()
print("Problem")
def close(self, info, is_ok):
print("Close")
return True
def _test_task_btn2_fired(self):
print("Button2 pressed.")
try:
loop.close
loop.create_task(self.model.test_task2())
except:
traceback.print_exc()
print("Problem")
def default_traits_view(self):
view = View(
Label("TesterLite"),
Item("test_task_btn", show_label=False ),
Item("test_task_btn2", show_label=False),
resizable=True,
title="MoteusControllerTesterLite",
height=400,
width=400,
)
return view
with loop:
print("Launching app.")
model = App()
view = AppView(model=model)
view.edit_traits()
print("edit_traits")
if sys.version_info[0] == 3 and sys.version_info[1] >= 8:
asyncio.events._set_running_loop(loop) # Need if using >= Python 3.8
loop.run_forever()
print("Finished run_forever()")
print("App closed.")
You have to use a flag that is used to terminate the while:
async def test_task(self, event):
while not event.is_set():
loop = asyncio.get_event_loop()
print("ok")
await asyncio.sleep(0.02, loop)
class AppView(ModelView):
"""Traits application view."""
model = Instance(App)
test_task_btn = Button("START1")
test_task_btn2 = Button("STOP1andSTART2")
event = asyncio.Event()
def _test_task_btn_fired(self):
print("Button pressed.")
try:
loop.create_task(self.model.test_task(self.event))
except:
traceback.print_exc()
print("Problem")
def _test_task_btn2_fired(self):
print("Button2 pressed.")
self.event.set()
try:
loop.create_task(self.model.test_task2())
except:
traceback.print_exc()
print("Problem")
def default_traits_view(self):
view = View(
Label("TesterLite"),
Item("test_task_btn", show_label=False),
Item("test_task_btn2", show_label=False),
resizable=True,
title="MoteusControllerTesterLite",
height=400,
width=400,
)
return view

Can I write to and read from a process in the same asyncio loop?

I have a process that reads input and writes output, like this doubler:
(in reality it's actually a black box and the input and the output are completely independent)
#!/bin/bash
while read -r i; do
sleep 0.$RANDOM
echo $((i*2))
done
and a few functions in my Python code that feeds this process asynchronously:
import asyncio
import subprocess
import random
class Feeder:
def __init__(self):
self.process = subprocess.Popen(['doubler.sh'],
stdin=subprocess.PIPE)
def feed(self, value):
self.process.stdin.write(str(value).encode() + b'\n')
self.process.stdin.flush()
feeder = Feeder()
async def feed_random():
while True:
feeder.feed(random.randint(0, 100))
await asyncio.sleep(1)
async def feed_tens():
while True:
feeder.feed(10)
await asyncio.sleep(3.14)
async def main():
await asyncio.gather(
feed_random(),
feed_tens(),
)
if __name__ == '__main__':
asyncio.run(main())
This works well. But I would like to read the output of the process too, like this:
...
stdout=subprocess.PIPE
...
for line in feeder.process.stdout:
print("The answer is " + line.decode())
but that is blocking, so the feeding won't happen. Can this be done in the same asyncio loop? Or do I need another thread?
Something like this should work. In order to read from stdout asynchronously you have to switch to asyncio.subprocess.
import asyncio
import random
class Feeder:
def __init__(self):
self.process = None
async def start_process(self):
self.process = await asyncio.create_subprocess_exec('./doubler.sh',
stdin=asyncio.subprocess.PIPE,
stdout=asyncio.subprocess.PIPE)
async def feed(self, value):
self.process.stdin.write(str(value).encode() + b'\n')
await self.process.stdin.drain()
feeder = Feeder()
async def feed_random():
while True:
asyncio.ensure_future(feeder.feed(random.randint(0, 100)))
await asyncio.sleep(1)
async def feed_tens():
while True:
asyncio.ensure_future(feeder.feed(10))
await asyncio.sleep(3.14)
async def read_feed():
while True:
line = await feeder.process.stdout.readline()
print("The answer is " + line.decode('utf-8'))
async def main():
await feeder.start_process()
await asyncio.gather(
feed_random(),
feed_tens(),
read_feed()
)
if __name__ == '__main__':
asyncio.run(main())

Categories

Resources