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

Minimal async-await foundations, updated #804

Merged
merged 3 commits into from Oct 27, 2021
Merged

Conversation

chitoyuu
Copy link
Contributor

This is an updated and rebased version of #709, that is no longer blocked on #757. Notable changes outside the original PR include:

  • TerminateInfo and InitializeInfo are moved back into the public API. These types are used as arguments to custom init/terminate callbacks. Custom callbacks are necessary for calling the gdnative_async register and terminate functions. Currently, they are just moved into the top level of gdnative_core, which I think makes sense given their usage in top-level callbacks. Please let me know if a better place is available.
  • Renamed the top-level re-export from asn to tasks, since the original author apparently didn't like it.

Supersedes #709

@Bromeon Bromeon linked an issue Oct 25, 2021 that may be closed by this pull request
@Bromeon Bromeon added c: core Component: core (mod core_types, object, log, init, ...) feature Adds functionality to the library labels Oct 25, 2021
Copy link
Member

@Bromeon Bromeon left a comment

Choose a reason for hiding this comment

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

Thanks a lot!

TerminateInfo and InitializeInfo are moved back into the public API. [...] Currently, they are just moved into the top level of gdnative_core, which I think makes sense given their usage in top-level callbacks. Please let me know if a better place is available.

It doesn't look like they are re-exported to gdnative with the current code, or at least they don't appear in its documentation. I generate it with:

cargo doc --no-deps -p gdnative --open

Maybe we can add them to a new gdnative::nativescript::init module? Or even gdnative::init, if we're planning to dismantle the nativescript (but this could also be done separately).


Note that I commented on a few parts that were just moved to a different file (didn't see the code was left unchanged until later). Might still be worth addressing.


Regarding the async intricacies, maybe someone more proficient than me should have a look at those details? But I'm also OK with merging to collect user feedback, it's anyway feature-gated.

Also, do you plan on writing an example or book entry for async godot-rust? Or should we look at tests -- or some external source?

bors try

gdnative-core/src/lib.rs Outdated Show resolved Hide resolved
gdnative-core/src/lib.rs Outdated Show resolved Hide resolved
gdnative-core/src/lib.rs Show resolved Hide resolved
gdnative-core/src/lib.rs Outdated Show resolved Hide resolved
gdnative-async/Cargo.toml Outdated Show resolved Hide resolved
Comment on lines 27 to 28
/// If the `spawner` object is not used, the method call will fail, output an error,
/// and return a `Nil` variant.
Copy link
Member

Choose a reason for hiding this comment

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

Which method call will fail? spawn_with() has no return type.

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 Godot side of it. Clarified in doc-comments.

gdnative-async/src/rt.rs Show resolved Hide resolved
gdnative-async/src/rt/bridge.rs Outdated Show resolved Hide resolved
bors bot added a commit that referenced this pull request Oct 26, 2021
@bors
Copy link
Contributor

bors bot commented Oct 26, 2021

try

Build succeeded:

Copy link
Contributor Author

@chitoyuu chitoyuu left a comment

Choose a reason for hiding this comment

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

It doesn't look like they are re-exported to gdnative with the current code, or at least they don't appear in its documentation.

Seems to show up for me with cargo doc. I'm not sure if it's --no-deps that changed the situation, as gdnative-core is technically a dependency. Otherwise try cargo clean maybe?

Maybe we can add them to a new gdnative::nativescript::init module? Or even gdnative::init, if we're planning to dismantle the nativescript (but this could also be done separately).

I think this is best done separately, as further discussion might be needed.

Also, do you plan on writing an example or book entry for async godot-rust? Or should we look at tests -- or some external source?

As the title of the PR suggests, this is just a minimal foundation. It's not meant to be the final user-facing API. I suppose I can do that if you'd like, but it will have to be replaced later when a higher-level API becomes available.

gdnative-core/src/lib.rs Outdated Show resolved Hide resolved
gdnative-core/src/lib.rs Outdated Show resolved Hide resolved
gdnative-core/src/lib.rs Show resolved Hide resolved
gdnative-core/src/lib.rs Outdated Show resolved Hide resolved
gdnative-async/src/rt/bridge.rs Outdated Show resolved Hide resolved
gdnative-async/src/rt.rs Show resolved Hide resolved
Comment on lines 27 to 28
/// If the `spawner` object is not used, the method call will fail, output an error,
/// and return a `Nil` variant.
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 Godot side of it. Clarified in doc-comments.

gdnative-async/Cargo.toml Outdated Show resolved Hide resolved
@Bromeon
Copy link
Member

Bromeon commented Oct 26, 2021

Seems to show up for me with cargo doc. I'm not sure if it's --no-deps that changed the situation, as gdnative-core is technically a dependency. Otherwise try cargo clean maybe?

Seems to work fine now, must have missed them somehow.
Let's do the module reorg separately, then.

As the title of the PR suggests, this is just a minimal foundation. It's not meant to be the final user-facing API. I suppose I can do that if you'd like, but it will have to be replaced later when a higher-level API becomes available.

Makes sense! Also, of course it doesn't have to be you in particular providing those resources.
It's great to have a foundation on which we can build 🙂

I think we should probably also update the CI release workflow, as there's a new crate to be published. Feel free to add a separate commit to logically separate changes.

bors try

bors bot added a commit that referenced this pull request Oct 26, 2021
@chitoyuu
Copy link
Contributor Author

Added the new crate to the workflow.

@bors
Copy link
Contributor

bors bot commented Oct 26, 2021

try

Build succeeded:

@Bromeon
Copy link
Member

Bromeon commented Oct 26, 2021

Will be merged tomorrow unless there are objections.

bors try

bors bot added a commit that referenced this pull request Oct 26, 2021
@bors
Copy link
Contributor

bors bot commented Oct 26, 2021

try

Build failed:

@Bromeon
Copy link
Member

Bromeon commented Oct 26, 2021

Latest CI passed, including nightly: https://github.com/godot-rust/godot-rust/actions/runs/1386329141

Copy link
Contributor

@jacobsky jacobsky left a comment

Choose a reason for hiding this comment

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

Thank you for the PR! I apologize for the late review, I've had to spread it out over a couple of days. All in all, it looks great! Thanks for all the help with this.

There is only one point that concerns me at the moment, and that's related to my comment about async being a default feature flag for gdnative. (Don't worry about changing anything yet, I just wanted to bring up the discussion).

@@ -12,18 +12,20 @@ readme = "../README.md"
edition = "2018"

[features]
default = ["bindings"]
default = ["bindings", "async"]
Copy link
Contributor

Choose a reason for hiding this comment

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

@Bromeon Do we want to make this a default feature for all users? As this is currently a minimal foundation, I was wondering if we should make it opt-in since it will likely add a bunch of dependencies and is only necessary if someone wants to use Rust's async functionality

Copy link
Member

Choose a reason for hiding this comment

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

I agree, I missed this. Would also vote for opt-in (at least once we release v0.10).

There were already reports of very long godot-rust compile times, no need to burden people more if they don't need async functionality.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No strong feelings. Done.

Copy link
Contributor

Choose a reason for hiding this comment

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

Thank you very much for the changes!

Copy link
Contributor

@jacobsky jacobsky left a comment

Choose a reason for hiding this comment

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

Based on the conversation, I am adding a quick request to remove async from the default features. It may be nice to add a quick section to the readme to mention the feature-flag, but that can also be addressed separately.

chitoyuu and others added 3 commits October 27, 2021 10:28
The types are used as arguments to custom init/terminate callbacks, and aren't
entirely internal.
This sets the foundations for async-await support in godot-rust, based on the
original idea in godot-rust#284. However, although the tests work, this is not a full
implementation:

- Async methods can only be registered manually using `build_method`. Macro
  syntax and implementation are out of the scope of this PR.
- The runtime types aren't registered automatically yet.
  Users need to manually call `register_runtime` and `terminate_runtime`
  functions in their library lifecycle hooks. Improving this is out of the
  scope of this PR for now.
- The crate is currently re-exported as `gdnative::asn`, instead of the much
  longer `async_yield`. The name is open to discussion -- I don't like it very
  much.
- Only local spawners are supported, due to issues with thread safety. Users
  may off-load tasks that don't contain `yield`-likes to thread pool spawners
  using something like `futures::future::Remote`, however.
- Panics in async methods don't currently behave very well. Their
  `FunctionState`-likes simply block forever and any outstanding bridge
  objects for futures can be leaked.
- `set_executor` and `register_runtime` are changed to allow multiple
  calls, at the expense of slightly worse error messages when they aren't
  called as necessary.
- Renamed the top-level re-export to `tasks` instead of `asn`.
- Added documentation for previously undocumented public items.
- Removed `async` from default features
Copy link
Contributor

@jacobsky jacobsky left a comment

Choose a reason for hiding this comment

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

Looks good to me! Thank you for all the hard work!

@jacobsky
Copy link
Contributor

@Bromeon I'm happy with all the current changes, do you have any additional feedback or should we go ahead and merge it?

@Bromeon
Copy link
Member

Bromeon commented Oct 27, 2021

As discussed in Discord, let's merge it.
Thanks to https://github.com/godot-rust/book/pull/44, we also have some examples for it! 🚀

bors r+

@bors
Copy link
Contributor

bors bot commented Oct 27, 2021

Build succeeded:

@bors bors bot merged commit 03c334e into godot-rust:master Oct 27, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
c: core Component: core (mod core_types, object, log, init, ...) feature Adds functionality to the library
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[discussion] Async-await support
3 participants