Replies: 17 comments 1 reply
-
Just curious, which one do you mean, Or do you mean the Sync Api for HttpClient in Runtime, which was heavily influenced by Azure SDK support back in the day. On Bluesky you wrote that for Message Consumers you have valid sync use cases, what are these? But why the consumers? They should be fairly easily adapted as you just need some kind of backgroundservice doing the async startup. |
Beta Was this translation helpful? Give feedback.
-
You may be interested to follow this thread: The ASP.NET team was forced to begin rolling back their change from .NET 5, and more so in .NET 6. Generally speaking, it is a bad idea to impose this decision on your users, because you cannot know their context. You do not know, as a library author, whether they should use async i/o or not. Some reasons that they might choose to be sync:
These are just some of the problems. The simple answer is that as a library designer, you cannot know. |
Beta Was this translation helpful? Give feedback.
-
But you have now made an assumption about the range of possible ways that I can write my code. async i/o is not "magic faerie dust". For example, local file i/o is generally faster via a blocking method than a non-blocking method, particularly as the CLR does not have truly asynchonous file i/o. A read-write to an SSD is faster via a blocking call than an async one. Do you know all your user's contexts? Do you know all their paradigms under which they will use their code? |
Beta Was this translation helpful? Give feedback.
-
As a framework author which uses RabbitMQ as one of our transports, and supports both sync and async for our users, because we don't want to assume their context, we would have to block over async to use this, or adopt a strategy of
around every RMQ call via an extension method wrapper for safety, to allow folks to continue to have a choice about their concurrency context. |
Beta Was this translation helpful? Give feedback.
-
Yeah that's the HttpClient change I was referring to, which was heavily influenced by Azure (as written in the first post and commented a lot in that thread) and specifically that the support is only partial.
No I'm not making assumptions. I understand that you want to provide the users of your framework a sync api. I'm just curious why you think message consumers being an interesting use case for sync, if I correctly understand your code in BrighterCommand's RMQ But I also think that the async code in the current iteration of the RabbitMQ library is far superior than the previous code, both in readability/maintainability and performance metrics, as it uses a lot of the more modern functionality provided by the dotnet team in recent years. Note: I don't have any skin in the game here, I just tried to provide you help to solve the problem of your sync consumer. |
Beta Was this translation helpful? Give feedback.
-
This seems to have been the problematic change: #1472 |
Beta Was this translation helpful? Give feedback.
-
It may be worth reading David's comments here: https://bsky.app/profile/keansbox.com/post/3lc3lop3ewc2w Async is a choice, and I make it when I want to choose co-operation over performance. In some cases, I may not want to choose co-operation. Software scales just fine without yielding to other threads all the time. For example, if I run a single-threaded worker in a container, I may well not choose to yield by using await; I may just rely on co-operative multi-tasking, because I want to optimise performance, reduce allocations etc. The reality here is this: the RabbitMQ SDK CANNOT know my context. So dropping support for sync is a strong opinion about the types of RabbitMQ consumers you are prepared to support. The answer here from Broadcom is: if you have legacy needs, if you want performance over co-operation, if you want a simpler programming model: we don't care, please use something other than RabbitMQ for your workloads. |
Beta Was this translation helpful? Give feedback.
-
There is very little specifics in this "request", so it belongs to a discussion.
We never claim anywhere that it is "magic fairy dust". A large percentage of active contributors have been asking for an "async first" interface for years. Now that we finally have it, apparently it's not good enough. The RabbitMQ core team is tiny, and we have the API that most contributors want. If you want an alternative, you are welcome to contribute it.
Is there a law of physics that states that ".NET SDKs" should or should not do this or that? I think it's a perfectly fine choice for a library that implements an inherently asynchronous messaging protocol to have an asynchronous interface. Having "sync alternatives" for a few key channel methods likely won't see much opposition as long as
|
Beta Was this translation helpful? Give feedback.
-
@iancooper are you willing to contribute such a "sync API" for at least connection, If you are not then I'm afraid our team does not have the resources to support two implementations of the protocol. I mean, we have just spent a few years moving to |
Beta Was this translation helpful? Give feedback.
-
Oh gosh, these are entirely different meanings of asynchronous. One is an asynchronous conversation, where both parties do not need to be present at the same time. The other is yielding your thread to await a call back via polling a completion port. They are not even close as ideas, and one does not indicate the other. |
Beta Was this translation helpful? Give feedback.
-
I guess the question would be how much the "fields have been sown with salt" and therefore it is to get back to a sync API. I will take a look. I know there was a PR, where you stripped out the sync API. It is possible that is a starting point, depending on why you stripped it at that point (problems with the way you were providing a sync API over the internals). A first step may be to wrap the async api calls, in as safe an approach as possible, because many clients will be forced into that; at least if it is done safely, although with a performance cost, in the a sync version of the api will be in a less bad place that we are now. From there I suspect we could look at fixing this, so that we don't force a concurrency model on the consumer.
|
Beta Was this translation helpful? Give feedback.
-
Yeah, I think that the advice that you received here was problematic, as it seems to have only reached a very narrow audience, who were focused on delivering the async API, not on the needs of actual consumers. |
Beta Was this translation helpful? Give feedback.
-
So, I think the first step is figuring out how to revert this change, and move forward from there. |
Beta Was this translation helpful? Give feedback.
-
So apparently you know better than the maintainers. This is an unbelievable level of arrogance. |
Beta Was this translation helpful? Give feedback.
-
@iancooper I will not take any more of this "I know better than the maintainers". We (the RabbitMQ Core Team) talk to the users of this library virtually every day, whether we like it or not. No one has objected to the async API that was under development for about three years or so. And now that the train is gone and you've missed it, you expect us to do a U-turn. I find it difficult to believe that there can be something meaningful contributed with this kind of disregard for what key contributors have spent several years on, all working in this repo in the open. |
Beta Was this translation helpful? Give feedback.
-
It's not every day that you run into a situation where a major revisit to an API of a popular library is in the works for about three years in the open, then the changes are finished and shipped, with many preview releases along the route, and then a non-contributor with very strong opinions shows up. But this is also not unheard of. Keeping a sync API in 7.x makes a certain amount of sense to allow for easier (and by that I do not promise "almost effortless" or "drop-in") upgrades to a version that has plenty of important internal improvements that also have been requested and worked on for a long time. So, Where Do We Go from Here?So the only productive option I see is to ask every major contributor to 7.0 to consider reverting #1472 for However, if the key maintainer and regular contributors do not agree to maintain the previous sync API on top of the new one, this debate will be settled once an for all, and those who really want a sync API would have to build it in a wrapper library (which no one prevents them from doing even today). Previous DiscussionsI also could find some indications that the key maintainer of this library, @lukebakken, had plenty of doubts about how a sync API can be supported and whether that would even be realistic, for example, in #1471. In #1471 (comment), Luke suggests that someone should contribute an implementation of one of those ideas and there were no takers. Which is fine, but demonstrates the level of interest amongst those who regularly contribute and participate in discussions. Which is not a good sign for the future of the sync API, if there's any, even as part of the |
Beta Was this translation helpful? Give feedback.
-
@iancooper the 6.x series is available for people who wish to continue using the old API. That version of the library has warts and could use some contributions from the community to fix them. Search issues and discussions for "ThreadPool", for instance. We welcome useful contributions to this project. |
Beta Was this translation helpful? Give feedback.
-
Is your feature request related to a problem? Please describe.
async/await is not SDK "magic faerie dust". Whilst it is important to support it, it is also important to support sync APIs.
If you do not support synchronous APIs you impose a design decision on all consumers of your SDK: you must use asynchronous i/o or you have to block on an asynchronous operation. The problem here is that blocking on an asynchronous operation is far worse of a problem, than using blocking i/o.
An async/await programming model is viral; it forces the whole program, from top-to-bottom to become async. This may or may not be a valid choice, but as an SDK owner, you cannot determine this
In addition, in some cases, blocking i/o may be a better option, so you should leave this open for clients.
I note that the ASP.NET team had to roll back their decision to provide only non-blocking APIs, for exactly the same problem space.
Generally, SDK writers should not make choices for their users, as they cannot know their context. Specifically, they should not choose their concurrency model in this case. You can be opinionated, and prefer some options over others, but always provide an escape route to allow your opinions to be avoided.
You don't have the context to decide if a consumer should use async/await.
Describe the solution you'd like
A #dotnet SDK should support both blocking and non-blocking operations, so as to not force design decisions on consumers of that SDK, or force dangerous behaviors such as blocking on async.
Please put the synchronous APIs back into the SDK, with immediate effect.
Describe alternatives you've considered
One alternative here is to fork the SDK, and to put synchronous approaches back into the SDK. This seems to be an unhelpful response, so it would be better to discuss why this SDK change should be reconsidered.
Additional context
It is great that there are now asynchronous APIs. But the support for asynchronous APIs should not come at the expense of imposing design decisions on consumers of your SDK.
Beta Was this translation helpful? Give feedback.
All reactions