Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Transition to asyncio #315

Open
ceccopierangiolieugenio opened this issue Jan 23, 2025 · 1 comment
Open

Transition to asyncio #315

ceccopierangiolieugenio opened this issue Jan 23, 2025 · 1 comment
Assignees

Comments

@ceccopierangiolieugenio
Copy link
Owner

No description provided.

@ceccopierangiolieugenio
Copy link
Owner Author

ceccopierangiolieugenio commented Jan 31, 2025

from discord:

I am having a look at the asyncio transition
at the moment it is not so easy due to the shift of paradigm,

the main issue I am facing is that;
I have a:

  • loop in a thread that retrieve the inputs and put them in a queue,
  • loop in another thread that pull the queue process the actions

if some action get slow
(i.e. if you run the demo as a window and you resize the entire window)
the framerate drop significantly but the drag action is still in place and the new drag positions are still collected in the queue.

so, I introduced a queue scrapping mechanism in the second loop before the actin is taken to removed the in between drag/move positions and process only the last one in the queue.

this is kind of easy using threads because you know that the first queue is filled also if the second thread got stuck with some heavyload operation.

but I am kind of struggling to reproduce this behavior using asyncio.
Thanks to copilot I am trying to simluate this behavior with te folowing code where I use time.sleep(2) as the heavy load routine involved.

import asyncio
import sys
import time

async def read_stdin(queue):
    """Coroutine to read lines from stdin and push them to the queue."""
    loop = asyncio.get_event_loop()
    reader = asyncio.StreamReader()
    protocol = asyncio.StreamReaderProtocol(reader)
    await loop.connect_read_pipe(lambda: protocol, sys.stdin)

    while True:
        # Read all available lines from stdin
        line = await reader.readline()
        print(f"Read: {line}")
        if line:
            queue.put_nowait(line.decode().strip())
        while not reader.at_eof():
            line = await reader.readline()
            print(f"Read: {line}")
            if line:
                queue.put_nowait(line.decode().strip())

async def process_queue(queue):
    """Coroutine to read lines from the queue and print them."""
    while True:
        lines = []
        # Collect all lines from the queue
        line = await queue.get()
        lines.append(line)
        queue.task_done()
        while not queue.empty():
            line = await queue.get()
            if line is None:
                return  # Stop signal
            lines.append(line)
            queue.task_done()

        # Print all collected lines
        if lines:
            print("Processed batch:")
            for line in lines:
                print(f" - Processed: {line}")

        await asyncio.sleep(0.01)
        print('Sleep ...')
        time.sleep(2)
        print('Sleep Done')


async def main():
    queue = asyncio.Queue()

    # Start the read_stdin and process_queue coroutines
    read_task = asyncio.create_task(read_stdin(queue))
    process_task = asyncio.create_task(process_queue(queue))

    # Wait for both tasks to complete
    await asyncio.gather(read_task, process_task)

if __name__ == "__main__":
    try:
        asyncio.run(main())
    except KeyboardInterrupt:
        pass

so far the first coroutine is able to collect all the input sent during the sleep
but still I don't know if this would introduce some delay in the inpput

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant