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

use async/await and update http, tokio #138

Closed
wants to merge 1 commit into from

Conversation

schrieveslaach
Copy link
Contributor

No description provided.

@schrieveslaach schrieveslaach changed the title update http requirement from 0.1 to 0.2 [draft] update http, tokio and use async/await Jan 3, 2020
schrieveslaach added a commit to aixigo/PREvant that referenced this pull request Jan 3, 2020
dkregistry-rs needs a newer version of tokio (see camallo/dkregistry-rs#138)
schrieveslaach added a commit to aixigo/PREvant that referenced this pull request Jan 3, 2020
dkregistry-rs and shiplift need newer version of tokio (see
camallo/dkregistry-rs#138 and softprops/shiplift#191)
@schrieveslaach schrieveslaach changed the title [draft] update http, tokio and use async/await use async/await and update http, tokio Jan 6, 2020
@schrieveslaach
Copy link
Contributor Author

@lucab, @steveej, this PR adds support for async/await. Please, have a look.

schrieveslaach added a commit to aixigo/PREvant that referenced this pull request Jan 6, 2020
dkregistry-rs and shiplift need newer version of tokio (see
camallo/dkregistry-rs#138 and softprops/shiplift#191)
sha2 = "^0.8.0"

[dev-dependencies]
env_logger = "0.7"
spectral = "0.6"
tokio = { version = "0.2", features = ["macros"] }
Copy link
Member

Choose a reason for hiding this comment

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

To the best of my knowledge, cargo will do a union of the features-set between this and the other tokio dependency.

You can either promote the macros feature to the other dependency, or avoid using macros in examples (my preference is for the latter). At that point, you can simply drop this line.

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 think and tested that dev-dependencies won't be exposed to users of this crate. If I try to use following code in a rust application, the compiler tells me that it cannot find the code that is only available behind the feature macros.

#[tokio::main]
async fn main() -> Result<(), Error> {
    // …
}
|
| #[tokio::main]
|          ^^^^ could not find `main` in `tokio`

src/errors.rs Show resolved Hide resolved
src/lib.rs Outdated Show resolved Hide resolved
Copy link
Contributor

@steveej steveej 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 for porting this to async/await! I had started the work before the holidays and was only halfway through.

When I did, I started looking into more ergonomic ways of streaming as I found them a bit cumbersome to use. I added it one of my comments but it's worth copying here that I want to experiment with using https://github.com/tokio-rs/async-stream. I don't want to necessarily block this PR on it though, and I'm fine working on the refactor myself or review yours in a subsequent PR, whatever you prefer.

Further notes (partially redundant with the comments as well)

  • Please make sure to have dependency commits separate and precede the other changes
  • Please add lines to your PR comment for automatically closing the existing dependabot PRs for the bumped dependencies

Cargo.toml Show resolved Hide resolved
src/lib.rs Outdated Show resolved Hide resolved

#[derive(Debug, Default, Deserialize, Serialize)]
struct Catalog {
pub repositories: Vec<String>,
}

impl v2::Client {
pub fn get_catalog(&self, paginate: Option<u32>) -> StreamCatalog {
pub fn get_catalog<'a, 'b: 'a>(&'b self, paginate: Option<u32>) -> StreamCatalog<'a> {
Copy link
Contributor

Choose a reason for hiding this comment

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

When I started to take at look at porting dkregistry to async/.await, I was pointed towards https://github.com/tokio-rs/async-stream for stream handling. Do you by chance have experience with it, or are otherwise willing to compare it to what's currently in this PR?

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 don't have any experience with it. Do you mind to clean this up in another PR?

Copy link
Contributor

Choose a reason for hiding this comment

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

That's fine by me.

Copy link
Contributor

Choose a reason for hiding this comment

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

After taking another look at the code and spotting the unsafe which is used within this function, I suggest the following:

Suggested change
pub fn get_catalog<'a, 'b: 'a>(&'b self, paginate: Option<u32>) -> StreamCatalog<'a> {
pub async fn get_catalog(&self, paginate: Option<u32>) -> Result<String> {

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Result<String> seems a bit limited too me because as a user I would have to parse the string. I think the method should return Result<Vec<String>>. What do you think?

Copy link
Contributor

Choose a reason for hiding this comment

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

Result<String> matches the previous Box<dyn futures::Stream<Item = String, Error = Error>>. If we return a Vec<String> here, the caller will collect into a Vec<Vec<String>> which then needs to be flattened to Vec<String>. It would be more convenient for the consumer to collect into that directly. #140 implements my suggestion.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Okay. I wasn't aware that you can use futures for streams. But it makes totally sense.

src/v2/mod.rs Outdated Show resolved Hide resolved
tests/mock/api_version.rs Show resolved Hide resolved
// TODO(lucab): implement pagination
assert_eq!(page2, None);
assert!(page2.is_none());
Copy link
Contributor

Choose a reason for hiding this comment

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

This change makes the panic less helpful because it hides the value which was received.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Unfortunately, I had to make this due to a limitation of error_chain:

Because the error type contains std::error::Error+Send + 'static objects, it can't implement PartialEq for easy comparisons.

The original code results in a compiler error:

|     assert_eq!(page2, None);
|     ^^^^^^^^^^^^^^^^^^^^^^^^
|     |
|     std::option::Option<std::result::Result<std::string::String, mock::api_version::dkregistry::errors::Error>>
|     std::option::Option<_>

What do you propose to improve the code?

let (end, _) = runtime.block_on(next.into_future()).ok().unwrap();
assert_eq!(end, None);
let (end, _) = runtime.block_on(next.into_future());
assert!(end.is_none());
Copy link
Contributor

Choose a reason for hiding this comment

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

same as above

let (end, _) = runtime.block_on(stream_rest.into_future()).ok().unwrap();
assert_eq!(end, None);
let (end, _) = runtime.block_on(stream_rest.into_future());
assert!(end.is_none());
Copy link
Contributor

Choose a reason for hiding this comment

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

same as above

schrieveslaach added a commit to aixigo/PREvant that referenced this pull request Jan 13, 2020
dkregistry-rs and shiplift need newer version of tokio (see
camallo/dkregistry-rs#138 and softprops/shiplift#191)
Copy link
Contributor

@steveej steveej left a comment

Choose a reason for hiding this comment

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

FYI, I'm currently working on this branch to figure out a solution to my requested changes so far. Also to fix the tests which are gated by the test-net feature. Do you have any preference of either getting my changes back into this PR, or me creating a new PR with my changes squashed into your commits?

"failed to parse url from string '{}': {}",
ep, e
)))));
)))]));
return unsafe { Pin::new_unchecked(b) };
Copy link
Contributor

Choose a reason for hiding this comment

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

I would really like to avoid the unsafe is possible, and I think it is, see: https://github.com/camallo/dkregistry-rs/pull/138/files#r365796988

@schrieveslaach
Copy link
Contributor Author

@steveej, how do you want to proceed with this PR? Do you want me to squash the commits and you finished the rest in #140?

@steveej
Copy link
Contributor

steveej commented Jan 20, 2020

@schrieveslaach

Do you want me to squash the commits and you finished the rest in #140?

That sounds good to me. I'll rebase on top of your squashed branch, then Github will automatically detect this one as merged. I'd appreciate if you could help review #140 as well!

- Add support for async/await
- Clean up dependencies
- Apply cargo fmt
- Bump next minor version
@schrieveslaach
Copy link
Contributor Author

@steveej, I squashed the commits. I will have a look at #140 in the next couple of days.

@steveej
Copy link
Contributor

steveej commented Jan 24, 2020

@steveej, I squashed the commits. I will have a look at #140 in the next couple of days.

Ah, thanks for that, but could I ask you to split the commtis which touch the Cargo.* files from the code changes, please? We have tried to separate these changes in case code changes need to be reverted without changing the dependencies at one point.

@steveej
Copy link
Contributor

steveej commented Jan 24, 2020

I took the liberty of helping you out with splitting up the commits while preserving your authorship as best as I could. Please take a look at the commit history of #140 and let me know if that's fine for you. I suggest we either close this PR and focus on #140, but I'll leave it up to you.

@schrieveslaach
Copy link
Contributor Author

@steveej, that's fine for me. 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants