Skip to content
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

shiny future: Barbara enjoys an async sandwich #174

Merged

Conversation

seanmonstar
Copy link
Contributor

Copy link
Contributor

@nikomatsakis nikomatsakis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like this, esp. the hints about some of the ways it might be done. Thanks @seanmonstar!

@nikomatsakis nikomatsakis added the shiny-future "Shiny future" stories or story ideas label Apr 28, 2021
@pickfire
Copy link
Contributor

pickfire commented Apr 28, 2021

Looks quite interested, a more flexible block_on, probably we want to see what is the performance cost of this.

Just wondering, now the difference is that block_on is able to run within sync code.

What if the user did not create any runtime but block_on was still called? Will the code get a runtime panic instead of compile time error?

Maybe we could have a global OnceCell and GhostCell like thing (feels like global variable) which can be enforced at compile time, to determine whether a runtime is being created? Maybe it could solve the runtime not found (runtime not created), runtime within runtime (runtime on top of runtime) and runtime feature not enabled (like io feature not enabled) issues with errors at compile time?

@nikomatsakis
Copy link
Contributor

What if the user did not create any runtime but block_on was still called? Will the code get a runtime panic instead of compile time error?

This is a good question to highlight. What happens in this scenario?

Perhaps also in a case where there are multiple runtimes.

@seanmonstar
Copy link
Contributor Author

What if the user did not create any runtime but block_on was still called? Will the code get a runtime panic instead of compile time error?

I imagined that calling block_on would have been basically what the #[runtime::main] attributes do, so it would also Just Work. It would however be more expensive then if someone set it up once. It might be possible to have it check a thread-local to prevent multiple creations, I haven't decided if this is a good or bad idea though.

Perhaps also in a case where there are multiple runtimes.

Could be an interesting separate story. There would be a lot of nuance to getting the implementation and decisions of that right. The original idea was that runtimes would all use futures::executor::enter() so that if mixed, they could at least detect the mixture and yell that it's a bad idea.

@pickfire
Copy link
Contributor

I imagined that calling block_on would have been basically what the #[runtime::main] attributes do, so it would also Just Work. It would however be more expensive then if someone set it up once. It might be possible to have it check a thread-local to prevent multiple creations, I haven't decided if this is a good or bad idea though.

Something like glibc runtime feature detection which is only done once and cached? See rust-lang/rust#68455 (comment)

# ✨ Shiny future stories: Barbara enjoys her async-sync-async sandwich :sandwich:

:::warning
Alternative titles:
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wasn't certain about the title, so I listed some alternatives. Now a few days later, I still prefer the original, but I can change if desired. Otherwise, I can just nuke this part first.


impl PermitRequest for HasHeader {
fn permit(&self, req: &Request) -> bool {
task::block_on(req_has_header(req))
Copy link
Contributor

@zeenix zeenix Apr 29, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While a block_on in std would already go a long way here, given how often this is needed, I wonder if we could do even better and provide a method on futures, so people can just use it like .await:

    req_has_header(req).block()

In fact, if it was up to me, I'd even want it as part of the language:

    req_has_header(req).block

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The original Future trait had a wait method, which did exactly that. We chose to remove it, because it was too easy for people to reach for instead of just letting the future be chained with others (now I'd say just .await). While I want to make it more forgiving in instances when a user has to do this, I'd still want to encourage users to try not to, since it is worse than using .await.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm.. wait can very easily be confused with await and I can see most programmers new to async, confusing them, but I see your point.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, I'm referring to Future v0.1, which existed before there was async/await syntax. People would often do things like this because of how easy it was:

first_fut.and_then(|val| {
    // a few lines of whatever
    let foo = do_another_future(val).wait();
    // and other lines
})

@nikomatsakis nikomatsakis merged commit f81eda6 into rust-lang:master Apr 29, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
shiny-future "Shiny future" stories or story ideas
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants