Async going blocking mode when there's no runtime #221
Labels
good first issue
Good for newcomers
help wanted
Extra attention is needed
status-quo-story-ideas
"Status quo" user story ideas
Brief summary
I will try to write my experience here as a story.
I am like Niklaus. interested in programming, could write basic programs.i thought i would make an API crate for a game i play called Guild Wars 2. The game provides the live player data (MumbleLink) like location, camera position/direction etc.. via shared memory. I run my game in wine and I wanted to expose it via a local server so other addons/overlays (which run on linux natively) can just use it as a library. and i would also support requesting data from servers about skills or other data which can be used by addons or web apps with seed.rs or yew.rs .
First, i wanted to deal with the shared memory. and as rust was a low level language and with winapi crate, it was really easy. for server, first i used std's udpsocket. was really easy too. but i thought i should expose a more proper api and i wanted to use grpc as its purely binary protocol. i choose tonic-rs to implement a grpc server. i was on windows and everything was working great. i boot to linux and find out that it crashes in wine. after a full day of debugging with println! statements, i see that mio was the crash reason. i find out that tokio-rs/mio#1444 , wine and haiku OS are not supported by mio. after reading about the usage of undocumented/legacy api, the first question i had was "why am i wasting so much time with this? this is not fun at all" and just gave up.there is only so much time/energy i can spend on any given hobby.
Second, i wanted to work on the api part of the crate. the question that popped up was, what to use as http client? because if i use a async client, i can't use it on wine. and if i use blocking, it is useless for web applications as a library. so... now i need to find a crate which supports both blocking and async clients, which can be turned on/off with feature gating. and obviously the popular crate called reqwest supports it. i tried to use it, and wine crashes. war flashbacks of debugging tonic. i immediately go into the source code to find that under the blocking api, reqwest actually has a async api. searching since forever, but there's either a async crate that exposes a thing blocking wrapper or a crate that's purely blocking. again, i was thinking that this was not fun. rust has tiered platform support. but rust async support is decided by third party crates and not rust itself as there's no official runtime.
So, i wondered. if i have to support both webapp and desktop /wine usage, do i need to write all api calls twice and feature gate async/blocking apis? for something so simple like making a request, what even is the difference?
and ofcourse, that's when i thought.
make_request().await
. if i have a runtime like tokio/asyncstd/smol, the compiler can use it as a state machine and swtich to other threads/tasks. but when there's no runtime, why can't the compiler just compile the function into a blocking code like ureq? if we had the ability to compile the async functions into blocking functions, i don't have to write my api twice with a [cfg(feature(async))] on all of the functions. and there will be no need for something like async-std to exist, as the whole std library can be made async and still be used by the programs as usual in a blocking manner. i am a newbie programmer and do not know what happens behind the scenes with futures or pins or all those fancy words. all i an think of is that for a long of common cases, writing func_call().await is just blocking code and join!(func_call().await, func_call2.await()) is parallel code like rayon's threadpool.Optional details
(Optional) Which [character(s)] would be the best fit and why?
Because he doesn't know much about the deeper issues of async/sync execution models and is more interested in doing safe correct projects with a faster language like rust without having to worry about the lower level details.
(Optional) What are the key points or morals to emphasize?
finally, i want to apologize in advance if i wasted people's time with this ridiculous idea. I have no idea about the intricate differences between async and sync execution models. what i am proposing might not be possible. this is just something i thought would be super cool for newbie rust programmers. just switching between async/sync rust binaries with a cargo option or such would make a lot of QoL improvements for library authors that want to support blocking and async apis.
The text was updated successfully, but these errors were encountered: