Asyncio queues in python and asyncua

Solution for Asyncio queues in python and asyncua
is Given Below:

I’m working with asyncio and asyncua libraries in python 3.8.7 and I want to use asyncio.Queue to pass the data from the async function into the main thread.

However, the issue I encountered is that my queue does not get any messages after the first await.

Here’s my example:

import threading
import time
import asyncio
from asyncua import Client
import aiohttp

async def main(queue1):
    queue1.put_nowait("main")
    client = Client(url="opc.tcp://localhost:4840/freeopcua/server/")
    #client = aiohttp.ClientSession()

    async with client:
        await queue1.put("in_async")
        queue1.put_nowait("in_async_2")

    queue1.put_nowait("after await")


def wrapper(queue1: asyncio.Queue):
    queue1.put_nowait("wrapper")
    asyncio.run(main(queue1))

if __name__ == '__main__':
    queue1 = asyncio.Queue()
    t = threading.Thread(target=wrapper, args=(queue1,))
    t.start()
    time.sleep(1)
    noEx = True
    while noEx:
        try:
            x = queue1.get_nowait()
            print(x)
        except asyncio.QueueEmpty:
            noEx = False

I get:

wrapper
main

If I use some other async lib (aiohttp in the example) then everything works as expected:

wrapper
main
in_async
in_async_2
after await

I have validated that minimal asyncua server at opc.tcp://localhost:4840/freeopcua/server/ server works – I can get the data using the code in this sample, but queues do not seem to work. Is there something I’m missing?

This is a bit of a guess on my part, but I think you have a race condition. Here is the while loop in the main thread:

while noEx:
    try:
        x = queue1.get_nowait()
        print(x)
    except asyncio.QueueEmpty:
        noEx = False

As soon as something prints, the loop will try to fetch the next thing in the queue. If the queue is empty at that instant, the while loop will exit and nothing will ever print again.

If the connection is made in your secondary thread quickly enough, the queue will get populated with the next two messages; but if there is a little bit of delay there, your main while loop may have exited before the messages get a chance to print. I am pretty sure that there is a possible (and unknown) network delay before entry into the async with: block.

I would try to insert a significant time delay after print(x) statement and see what happens (you can improve the code later if this fixes the problem). Or change the while loop so it just runs forever, since you can always exit the program with control-C.