-
-
Notifications
You must be signed in to change notification settings - Fork 550
Add trio implementation #1628
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
base: main
Are you sure you want to change the base?
Add trio implementation #1628
Conversation
So, while working on my own version, I started wondering if the Another big change I had to make was the introduction of |
@agronholm The Assembler is an implementation detail: it isn't documented in the API. It could live in the connection module. It happens to be an independent piece with medium complexity, which justifies giving it its own module. That keeps the connection module simpler. This is a personal preference in how I organize the code with no user-visible consequences. |
websockets got its own async test harness before there was one in the stdlib. The legacy implementation still uses it. I switched to I chose to stick to vanilla choices everywhere. websockets has no required dependencies, even for development. I am clearly biased by:
|
OK, so is the introduction of |
Incidentally, this is the primary reason why I steer clear of Django. |
Mastery of pytest isn't the problem. I used it in a professional context before. I know how to configure it. Actually, I spent a lot more time deep in the guts of the fixtures system than I ever wanted... It's simply not suitable considering my goals and constraints for this project. Keeping complexity and the amount of third-party code that I may have to understand or debug to the bare minimum ranks very high on the list. You're welcome to use it as a test runner though. |
Sure, it's your project, your rules. But I've just been thinking how much of the maintenance burden you could shed by relying on external projects rather than inventing everything yourself. Just my two cents. |
62e304c
to
09b9947
Compare
So are you going to continue with your work of adding a Trio-specific back-end? The pushes seem to indicate as much. Would you not rather let me finish my work on the AnyIO back-end? |
1051bfc
to
30fdd95
Compare
Short, directional answer because it's 11:30pm here:
|
I don't understand. Why even suggest adding anyio AND trio back-ends when the former caters for both Trio and asyncio users? The biggest reason would be fewer parts to maintain, not more! |
Indeed, if I finish the trio implementation within a reasonable timeframe, there's little point in an anyio implementation. As all things open-source, completion is highly dependent on everything else in my life; it isn't done until it's done :-) I see your frustration that I'm not taking advantage of anyio when you built it exactly for people like me. It's fine to disagree. However, I tried to understand where our views diverge to make sure I'm not missing something. Going straight to the point: 1/ I don't have a significant cost of maintenance for code that I control. I invest upfront in getting it right. The cost of maintenance is driven by changes in code outside of my control, whether intentional or not. asyncio is outside of my control and has been painful in this regard. trio and anyio are outside of my control; they may be less painful as asyncio but still it's more code outside of my control. (Of course anyio is under your control so you have the opposite perspective here.) 2/ This is a hobby project for me. I spend time writing code in websockets because I like coding and I don't get the opportunity to write meaningful code in my current job. Some people do crosswords; I do open-source. It's time well spent, even if others have written similar code before. I wrote an unconventional HTTP parser; it does exactly what I want and never caused problems; I found that interesting. Conversely, I get less joy of creation from diagnosing what changed in someone else's code and suddenly caused websockets to misbehave or from reviewing someone else's contribution so I'm not looking to spend more time on these activities. |
Funnily enough, you're making my point for me. If you proceed with your current plan of adding a Trio backend, you will end up with two async back-ends, either one of which may break when the upstream makes changes. But if there was only the AnyIO back-end, then |
This sounds like you're talking down to me. Please, let's have a constructive conversation or leave it there. I'm clear on where I disagree with you. I'm trying — and, for now, failing — to land this conversation on a respectful agreement to disagree. You're saying that using anyio will result in a lower maintenance cost. I don't buy it. I don't think there's a clear cut winner between:
(This isn't a full decision matrix; that's not my point; my point is that you have pros and cons on both sides.) It's similar building a Swift and Kotlin apps or a React Native app: both options are valid, depending on your preferences and constraints. Based on how this conversation went, it doesn't look like there's a path for smooth collaboration. Therefore, I won't consider a PR adding an anyio backend to websockets. |
Alright, thank you for the elaborate response. At least I tried. And sorry if I sounded like I was talking down to you – it was never my intention. |
No worries. Feels like we fell into a typical trap of open-source collaboration :-( If you have a WIP version of your anyio implementation somewhere, I'm genuinely interested in reading it because it will help me get a better grasp of anyio and structured concurrency (which I have no experience with). |
Here it is: https://github.com/agronholm/websockets/tree/anyio |
c224f28
to
1c346bd
Compare
635cb5d
to
9888470
Compare
Client is now feature-complete with 100% test coverage, although there's a bit of proof-reading and cleanup left. Moving on to server. |
I am debating whether the method to close i/ connections and ii/ servers should be called Consistency with Trio Trio usually provides a Trio doesn't provide an abstraction for servers. Servers are just lists of listeners accepting requests. You close them by cancelling listeners. There's no prior art here. However, we can reasonably assume that a server class would implement the Relying on cancellation to close a server is impractical for us because that would cancel every coroutine, including the coroutine pumping data from the network to the Sans-I/O stack, which must continue running until the TCP connection is closed to achieve a graceful shutdown. Implementing a clean shutdown in a cancellation context would require an extensive amount of shielding and create too much risk to introduce bugs where cancellation wouldn't work anymore. That's why we need an Consistency with WebSocket The argument that In the asyncio implementation, Conclusion Given our focus on providing I/O layers that feel native, using We should implement the semantics of UPDATE
|
4ca3810
to
56fde96
Compare
3341352
to
6f7bf08
Compare
Green build. Woohoo. Still a few fixes + full proof-reading necessary. |
Indeed, trio has no equivalent of asyncio.wait.
Also uniformize code & tests with other implementations.
Uniformize other implementations.
Also uniformize code & tests with other implementations.
No description provided.