I need to asynchronously execute a function and then save the return value for it to be returned when I need it.
I have the following code:
class EncodingThread(Thread):
def __init__(self):
Thread.__init__(self)
self.value = None
self.frame = None
def setFrame(self,frame):
self.frame=frame
def run(self):
self.value = mqtt.publish_message(self.frame)
thread = EncodingThread()
#some function
def somedef():
while True:
#keep in mind that this function does other stuff that I don't want to be disrupted by this routine, so the routine below should be asynchronous
thread.setFrame(some_value)
thread_status = thread.is_alive()
if not thread.is_alive():
thread.join()
if not thread_status:
results = thread.value
if results != (1 and None) :
value = results['request']
return value
The "mqtt.publish_message" function is an async function (using asyncio). If I don't use it, the codeflow "stops" to execute it, and I don't want this happening.
Also, currently I am getting the "TypeError: 'coroutine' object is not subscriptable" error on the line "value = results['request']"
How do I make this code work as intended, where "mqtt.publish_message" is executed asynchronously and the thread accordingly stores the return value of ""mqtt.publish_message" 's execution?
Thank you
CodePudding user response:
Fixing the asyncio issue is not going to completely fix this code. As soon as you start the EnclosingThread, its run method will execute; at that point, the variable self.frame
is None. When you try to set it by calling thread.setFrame(some_value)
, that will be too late: the call to publish_message
has already happened in the other thread, and mqtt is already off and running with wrong argument.
To answer your explicit question, secondary threads do not have a default event loop. It must be created and then set before running any async code in that thread, something like this:
def run(self):
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
self.value = loop.run_until_complete(mqtt.publish_message(self.frame))
I don't know anything about mqtt, so you should check to see if it's threadsafe. It is possible that mqtt must be initialized somehow, and that has to be done in the same thread where it's used. The code may fail because of that.