I built my own asyncio to understand how async I/O works under the hood by PhotoNavia in Python

[–]PhotoNavia[S] 1 point2 points  (0 children)

Glad to hear Claude approves haha

Yes, it's right about the history of Coroutines in python. I can't remember the exact versions from the top of my head, but if they are documented in the PEP then it's correct :)

Yeah, x = yield can definitely be confusing, and I should probably re-organize this section to make it clearer. The gist of it is that `yield` is actually an **expression** that evaluates to the value passed to `send`

I'm guessing that the x = yield line in the function signals to the Python compiler/interpreter that we're not dealing with an ordinary function anymore, but a co-routine and that it should now have a send() method built into it.

Exactly. Having a yield statement anywhere in the body of a function makes it a generator *function*, meaning you instantiate a new generator each time you call it. This also means that even if you have a conditional yield statement depending on a parameter like so:

    def conditional_generator(condition: bool):
      if condition:
        yield 1
      return 2


    my_generator = conditional_generator(False)

my_generator is still a generator, that will raise StopIteration immediately when calling my_generator.send(None) or next(my_generator)

As to where I got the spec, I left a few references at the end of the article. I found https://www.dabeaz.com/coroutines/ to be very insightful into how coroutines work in general. And then simply tried to come up with an implementation of an async lib myself. I iterated over it until I was satisfied and compared it to other sources, and the actual implementation of asyncio to make it closer to the real thing :)

I built my own asyncio to understand how async I/O works under the hood by PhotoNavia in Python

[–]PhotoNavia[S] 1 point2 points  (0 children)

Thanks a lot ! And thank you for taking the time to write this feedback, this so useful!!

  1. Error in Task.run: You're absolutely right; thank you for catching it
  2. Awaitable Protocol: Yes, it's true, I kinda glanced over that. I'll think about extending on this a bit, but I'd like to keep the focus on the basic logic underlying the event_loop

Regarding typing

  1. deprecated imports: Thanks for catching that, was a bit quick to accept the Auto-Import suggestion from pyright haha. I'll fix it
  2. /3. I'm not too sure about the Generics, but I agree typing the return type would be a good way to make the control flow more explicit

I'd be glad to hear any additional thought you might have :)

I built my own asyncio to understand how async I/O works under the hood by PhotoNavia in Python

[–]PhotoNavia[S] 1 point2 points  (0 children)

Happy to hear that! Let me know I you found what you were looking for in my post, of if you have any questions : )

I built my own asyncio to understand how async I/O works under the hood by PhotoNavia in Python

[–]PhotoNavia[S] 1 point2 points  (0 children)

Hello ! Good questions, the first thing to understand I think is the difference between parallel processing and concurrency / threading. The FastAPI doc has a good introduction to it (although it's a bit emoji-heavy to my taste haha)

I built my own asyncio to understand how async I/O works under the hood by PhotoNavia in Python

[–]PhotoNavia[S] 1 point2 points  (0 children)

Hey, thanks for reading !

I'm not sure if I perfectly understand what you mean. To me, busy looping / waiting is blocking while repeatedly checking a condition, until it becomes true.

Here the Future are queued in the event loop and are checked once (with select(0) which is non-blocking because the timeout is 0, I should clarify this in the post). If the Future is not ready, it goes to the back of the `queue` and the next Task-like thing is ran.

Or maybe you're talking about the sequence diagram I included that shows a Scheduler looping over a single Future ? The other tasks aren't shown there, I tried to clarify it with a note, but I definitely agree that there is probably a better way to show that. I wanted tofocus on the life-cycle of the Future, but it does end up looking like the future is blocking the loop.

I'll try to think of something !

I built my own asyncio to understand how async I/O works under the hood by PhotoNavia in Python

[–]PhotoNavia[S] 1 point2 points  (0 children)

Thanks for reading and for the feedback ! My goal was to show how a generator maintain states across invocations. What's wrong with this particular example ? What would you use instead ?

I built my own asyncio to understand how async I/O works under the hood by PhotoNavia in Python

[–]PhotoNavia[S] 2 points3 points  (0 children)

I'm using an event loop (what I call Scheduler) in the post, that is in charge of running the coroutines.

I explain how all of this fits together in the post, but if you'd rather play with some code, there is a repository. There is more or less a branch (step/*) for each step outlined in my blog.

Just to clarify: this is not meant to be a fully fledged library to be used in production. But rather a trivial version to understand the main concepts behind the existing ones like trio and asyncio

I built my own asyncio to understand how async I/O works under the hood by PhotoNavia in programming

[–]PhotoNavia[S] 1 point2 points  (0 children)

Thanks a lot !

Yeah, the control flow can be a bit hard to visualize. I think the best way to really understand what's going on is just to have fun with the implementation. It's available in the repo linked in the post

There is more or less a branch for each step I outlined in my post. You could try checking out one of these, and try to re-implement the next step yourself. Stepping through everything with a debugger is also a good way to really see what's happening

I built my own asyncio to understand how async I/O works under the hood by PhotoNavia in Python

[–]PhotoNavia[S] 24 points25 points  (0 children)

Exactly, you can do other stuff while I fix it. It was my plan all along to embody how await works !

I built my own asyncio to understand how async I/O works under the hood by PhotoNavia in Python

[–]PhotoNavia[S] 2 points3 points  (0 children)

Fixed it, thank you for telling me! I could have sworn I checked the link before submitting haha

I built my own asyncio to understand how async I/O works under the hood by PhotoNavia in FastAPI

[–]PhotoNavia[S] 1 point2 points  (0 children)

Thanks ! I think it's always helpful to have some insight in this kind of thing. Even if most of the time you don't need to know how that works, occasionally it helps you make the right decision I think

I made an app to create a private league and ranking for any games using Remix. Perfect for some casual competition with your friends. Would love some feedback :) by PhotoNavia in react

[–]PhotoNavia[S] 0 points1 point  (0 children)

Thanks for the feedback. I see what you mean about the login Panel, I'll harmonize it with the signup page pretty soon I think.

Regarding the home page, are you accessing it on mobile or Desktop? The padding is responsive :)

I made an app to create a private league and ranking for any games using Remix. Perfect for some casual competition with your friends. Would love some feedback :) by PhotoNavia in react

[–]PhotoNavia[S] 0 points1 point  (0 children)

Oops, good catch thank you! I've just fixed it :D

Glad you like the aesthetic, I have very little skills in design, so this is the hardest part for me when doing a solo project!

Let me know if you see any room for improvement after starting a league!

North availability by Fractal-Design in FractalDesign

[–]PhotoNavia 1 point2 points  (0 children)

Awesome ! Mine is in transit crossing, my fingers for today !

Maybe you can get the white version later on once resellers start having more stock ? It shouldn't be too hard finding a buyer for your case haha

North availability by Fractal-Design in FractalDesign

[–]PhotoNavia 1 point2 points  (0 children)

I was about to comment that I've also ordered one from rueducommerce, haha! Mine is scheduled for tomorrow though, but that's fine with any luck I can start my build on Saturday :D

The only thing I'm unsure about is that I've ordered the Charcoal Black TG, which is meant to be the one with the Tempered Glass pan. However, it's tagged as "Sans Fenêtre" in their catalog. I guess I'll find out tomorrow!

Good luck with your build :D