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

own request Bytes & to_json #145

Merged
merged 8 commits into from
Jan 18, 2021
Merged

own request Bytes & to_json #145

merged 8 commits into from
Jan 18, 2021

Conversation

ctaggart
Copy link
Contributor

I'm looking to integrate the services with the http_client interface, but want to make a couple of adjustments before I do. Here is the first one. Instead of serde_json::to_string, serde_json::to_vec is used. This avoids going from string to bytes later.

sdk/core/src/http_client.rs Outdated Show resolved Hide resolved
sdk/core/src/http_client.rs Outdated Show resolved Hide resolved
@@ -13,7 +14,7 @@ where
ContentTypeSet: ToAssign,
{
attachment_client: &'a AttachmentClient,
body: Option<&'b [u8]>,
body: Option<Bytes>,
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'm not sure about this change. I don't really know how CreateSlugAttachmentBuilder is used. If It is reused, this should be a &Bytes then cloned.

Copy link
Contributor

Choose a reason for hiding this comment

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

According to the docs (https://docs.rs/bytes/1.0.1/bytes/) bytes uses ref counting so cloning should be relatively cheap. I'd go with the owned struct.

@@ -94,7 +95,7 @@ where
}

impl<'a, 'b> CreateSlugAttachmentBuilder<'a, 'b, Yes, Yes> {
pub async fn execute(&self) -> Result<CreateSlugAttachmentResponse, CosmosError> {
pub async fn execute(self) -> Result<CreateSlugAttachmentResponse, CosmosError> {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Same here, if it is used many times, this should be changes back to &self.

Copy link
Contributor

Choose a reason for hiding this comment

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

Generally speaking, the idea of taking &self in execute is to make it easier to implement retry (Azure services can be offline, throttled, etc...).
We do not have such code now but this is something we might want to implement (paired storage regions, HA endpoints in CosmosDB, etc...).

Also, for streaming requests, we could (theoretically) reuse the same struct at each request and just change the next marker.

You proposed change to use bytes partially solves the issue since it's refcounted anyway.

) -> Result<Response<Vec<u8>>, Box<dyn std::error::Error + Sync + Send>> {
let mut reqwest_request =
self.request(request.method().clone(), &request.uri().to_string());
for header in request.headers() {
reqwest_request = reqwest_request.header(header.0, header.1);
}

let body = String::from_utf8(request.body().to_vec())?;
Copy link
Contributor Author

@ctaggart ctaggart Jan 15, 2021

Choose a reason for hiding this comment

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

The problem here is that byte array reference gets cloned with to_vec & then converts it to a string, only to have the string converted to bytes later. It is more efficient to own the bytes and send them without the conversions.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes you are right, the string conversion is not really necessary.
Also the idea to use ref counting here (by using bytes) is really good. 👍 👍

@ctaggart ctaggart marked this pull request as ready for review January 15, 2021 07:00
@MindFlavor
Copy link
Contributor

I really like this idea. bytes can help us avoid unnecessary allocations while keeping the code clean. 🥇 🥇

pub fn body(self, body: &'b [u8]) -> CreateSlugAttachmentBuilder<'a, 'b, Yes, ContentTypeSet> {
pub fn body(
self,
body: impl Into<Bytes>,
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@rylev, like this with impl Into<Bytes>?

@ctaggart
Copy link
Contributor Author

The storage rewrite in #119 was merged in, so I had to update storage as well. @MindFlavor, can you do another review please with the updates from c99bbc0?

@MindFlavor
Copy link
Contributor

I like it, the examples showcase clearly how good this decision is! 👍

@MindFlavor MindFlavor merged commit e1da0cd into Azure:master Jan 18, 2021
@ctaggart ctaggart deleted the http_client branch January 18, 2021 15:55
@ctaggart ctaggart mentioned this pull request Jan 18, 2021
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