@bf55f1f1 "I would like to see more web frameworks that are synchronous by default and allow you to opt into async as needed." I don't think that this is possible without maintaining two separate codebases/APIs like reqwest does. reqwest is just a client. But maintaining two APIs in parallel for a whole framework?
@bf55f1f1 One could create a new web framework that is synchronous which offers trivial parallelization (launch multiple instances). But how do you share state then without a database? A required database increases the complexity. And what about performance? Such a framework would not have the same performance like Axum. Who would use it then?
@bf55f1f1 If such a framework is targeted to newcomers, do you think many newcomers try Rust because of its reliability etc? I don't think so. I think that many of them, especially in the web ecosystem, come for the performance and low resource consumption. I would guess that most of them already have experience in Node, Python and Ruby. They know a slow solution. Why would they use that framework?
@bf55f1f1 So I guess that only people would use it who are already familiar with Rust and convinced by it and they want to build a backend. But then, if they are already sold on Rust, wouldn't they just learn async? The route for newcomers before they can work with Axum and SQLx is longer than other routes which don't include async. But for people who are familiar with Rust, it is just one step: Learning async. And I think that we currently have a problem of documentation here as you mentioned.
@bf55f1f1 My conclusion would be: - Improve the documentation of async - Make this difficulty levels clear to newcomers to climb up step by step: sync single threaded < sync multithreaded < async single threaded < async multithreaded - Stabalize missing async features like async traits (work in progress) - Try to reach having libraries agnostic regarding the async runtime (lowest priority for me personally since we have Tokio)
@5150cec1 oh, what I meant was that the framework would be sync like `iron` or the old versions of `rocket` and all endpoints would be sync. If you need async, you'd have to start a runtime, handle all futures, and return the results. No magic, no hidden runtime, very explicit. We should make running a few futures concurrently as easy as possible.
@bf55f1f1 But starting a runtime involves some overhead. Did I get it right that you would start a runtime for each request? I am not familiar with iron though and only tried a recent version of Rocket. About the hidden runtime: Why do you think that it is hidden? For me, it is very implicit since you annotate your main function with a tokio macro. Maybe because of the macro hiding how the runtime is launched? One can see its equivalence here: https://docs.rs/tokio/latest/tokio/attr.main.html#usage
@5150cec1 yeah, that's what I mean. Without looking into the cargo.toml, there is no way of figuring out whether it uses a single threaded or multithreaded runtime unless the annotation is more explicit than the default, which not what many people use.
@bf55f1f1 The Cargo.toml will not necessarily tell you about that if the feature "full" in Tokio was used. One needs to check where the runtime is spawned (noramally at the main function). The multithreaded version is the default. Otherwise you would see this explicit annotation: #[tokio::main(flavor = "current_thread")] I am sorry if I am missing something, but I don't get how the runtime that you normally start yourself (for example in Axum) is hidden.
@5150cec1 you're right. I was of the opinion that it would choose the runtime based on the activated features, which isn't the case. Then people "just" need to know what `#[tokio::main]` does. Not that much of an issue, but still more implicit than I'd like to.
@bf55f1f1 Basically syntax sugar for the default use case. But you can do it manually and even have more control if you want: https://codeberg.org/mo8it/oxi-axum-helpers/src/commit/3886ca460032ac47a0f88582abe507094166f743/src/runner.rs#L10