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

Allow futures on Serve and Stub to be Send #448

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

ShaneMurphy2
Copy link
Contributor

Not sure if this approach is the right one, so this MR is a draft.

@tikue
Copy link
Collaborator

tikue commented Apr 12, 2024

Sorry for the delay in reviewing! Will try to look in the next week.

@tikue tikue marked this pull request as ready for review April 24, 2024 05:37
Copy link
Collaborator

@tikue tikue left a comment

Choose a reason for hiding this comment

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

This looks like a reasonable change to me. Doesn't Serve need to be made a trait variant, too? Also, could you add some tests demonstrating how it will work for users?

@@ -66,6 +68,27 @@ impl Config {
}
}

/// A [`Stub`] implementation that simply warps a `Serve`.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nit: typo

Suggested change
/// A [`Stub`] implementation that simply warps a `Serve`.
/// A [`Stub`] implementation that simply wraps a `Serve`.

@@ -66,6 +68,27 @@ impl Config {
}
}

/// A [`Stub`] implementation that simply warps a `Serve`.
pub struct ServeStub<S> {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Maybe keep this type private for now and return an imp Stub? Can always make it public later if needed.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good idea

@ShaneMurphy2
Copy link
Contributor Author

This looks like a reasonable change to me.

Perfect, that's what I was looking for by putting up an early draft.

Doesn't Serve need to be made a trait variant, too?

Probably, was just focusing on my use case a little too much 😅

Also, could you add some tests demonstrating how it will work for users?

Will do, as I mentioned this is an early draft to make sure the change makes sense.

@ShaneMurphy2
Copy link
Contributor Author

I'll get back to this in a day or so, thanks for the review!

@ShaneMurphy2
Copy link
Contributor Author

Haven't forgotten, just wrapped up in other stuff. I'll try to get to it soon!

@ShaneMurphy2
Copy link
Contributor Author

Looks like trait_variant::make doesn't support default implementations in trait definitions. I could update the macro in that crate, thoughts?

Also, how do you feel about renaming Serve and Stub to LocalServe and LocalStub so that the "default" type is Send, seems like the more common use case potentially.

@ShaneMurphy2
Copy link
Contributor Author

I've given it some more thought and I'm wondering if the right move is to instead have a feature flag that annotates all traits with async methods in them with async_trait. Thoughts @tikue?

@tikue
Copy link
Collaborator

tikue commented Jun 22, 2024

I also just saw rust-lang/rfcs#3654. Wonder how long it will take to be available on nightly?

@ShaneMurphy2
Copy link
Contributor Author

ShaneMurphy2 commented Jun 24, 2024

I also just saw rust-lang/rfcs#3654. Wonder how long it will take to be available on nightly?

Looks like even post-implementation the RFC still recommends the pattern provided by trait_variant: https://github.com/nikomatsakis/rfcs/blob/rtn/text/0000-return-type-notation.md#rtn-supports-convenient-trait-aliases
https://github.com/nikomatsakis/rfcs/blob/rtn/text/0000-return-type-notation.md#guidelines-and-best-practices

@0xdeafbeef
Copy link

Sorry for ping, any updates?

@ShaneMurphy2
Copy link
Contributor Author

Sorry for ping, any updates?

I'm currently using my fork's branch trait-variant and it seems to work fine. Probably that could be merged soon since it is backwards compatible with the old way, as it only adds Tokio* types that bound the futures to be Send.

Copy link
Collaborator

@tikue tikue left a comment

Choose a reason for hiding this comment

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

Hey @ShaneMurphy2 taking another look at this in a while. Are you still interested in getting this merged?

Also, I'm kind of curious about trying out a feature-gated implementation that uses return-type notation rather than trait_variant. Some related thoughts on #480

@@ -16,6 +14,7 @@ mod mock;
/// A connection to a remote service.
/// Calls the service with requests of type `Req` and receives responses of type `Resp`.
#[allow(async_fn_in_trait)]
#[trait_variant::make(TokioStub: Send)]
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nit: maybe just call it SendStub?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure!

tarpc/Cargo.toml Outdated
@@ -49,7 +49,7 @@ pin-project = "1.0"
rand = "0.8"
serde = { optional = true, version = "1.0", features = ["derive"] }
static_assertions = "1.1.0"
tarpc-plugins = { path = "../plugins", version = "0.13" }
tarpc-plugins = { path = "../plugins", version = "0.13", registry = "umbra"}
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is the registry = "umbra" bit supposed to be here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Nope, coworker pushed to the wrong branch.

@@ -77,6 +100,16 @@ pub trait Serve {

/// Responds to a single request.
async fn serve(self, ctx: context::Context, req: Self::Req) -> Result<Self::Resp, ServerError>;

/// Wrap this `Serve` in a type that implements [`Stub`].
async fn into_stub(self) -> ServeStub<Self>
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can you remind me why the blanket impl for Serve impls had to be removed?

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 the compiler was complaining about conflicting trait implementations.

@ShaneMurphy2
Copy link
Contributor Author

Hey @ShaneMurphy2 taking another look at this in a while. Are you still interested in getting this merged?

I'm ambivalent on getting it merged as I think we can do better with the API, and I'm not confident this is the right approach in the general case. It works for our use case and a fork is ok for us for now.

Also, I'm kind of curious about trying out a feature-gated implementation that uses return-type notation rather than trait_variant. Some related thoughts on #480

That could be neat, I agree with your sentiment about being "forward thinking".

In a similar vein with using feature-gating, it could be nice to put the async_trait macro on all the traits behind a feature gate. That macro makes async traits very ergonomic for folks who can afford the performance hit.

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