-
-
Notifications
You must be signed in to change notification settings - Fork 439
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
Futures Sync #951
Futures Sync #951
Conversation
What is the rationale for needing Sync futures? |
I'm writing a library, where I want to pass an async function as the argument to another async function. After a little struggle I've managed to get async fn handle_simple(
&mut self,
handler: &'static dyn (Fn(String) -> HandlerResult),
) That could not work, because of the
So the solution was to make Fn sync. async fn handle_simple(
&mut self,
handler: &'static (dyn (Fn(String) -> HandlerResult) + Send + Sync),
) { And, as I was using tokio_postgres, I've encountered TLDR; When one is using tokio-postgres from async function passed to an async method
Yep. It's just a simple (working) concept of what can it look like. I was wondering, if there can be flag, that will simply add |
What type is You may want to use https://docs.rs/sync_wrapper/latest/sync_wrapper/struct.SyncWrapper.html to wrap the futures in something that implements Sync in your own code. |
Oh. I forgot to include its declaration. It's a future HandlerResult: Future<Output = (String,i8)> + Sync + Send
I was already struggling with it, but I could not manage to use it in my case. Obviously I'm still looking for using it, instead of this PR |
Ok. I've got an idea. As of now, the changes for async require only a little replace in
As it was previously said, the best option would be to make this feature a non breaking change. The easiest way of doing it may be using a codegen to copy This will allow to create a separate crate, let's name @sfackler what do you think? Is this acceptable? |
That is a thing you could make, but I am not particularly interested in maintaining. Creating copies of every async library you want to use with |
Yey! I've finally managed to avoid unnecessary code duplication in this repo. The hack was (simply) to use wihin my code following type for the arg #[async_trait]
pub trait SimpleHandling<HandlerResult>
where
HandlerResult: Future<Output = (String,i8)> + Send
{
async fn handle_simple(&mut self, handler: impl (Fn(String) -> HandlerResult) + Send + Sync);
} That allowed to use non Also, I'm very grateful for instructions, discussion and code reviews. Thanks! EDIT: To allow passing fn across threads I had #[async_trait]
pub trait SimpleHandling<HandlerResult>
where
HandlerResult: Future<Output = (String,i8)> + Send
{
async fn handle_simple(&mut self, handler: Arc<impl (Fn(String) -> HandlerResult) + Send + Sync)>;
} |
This solution is horrible (especially the one the repo's owner linked) and actually led me to have to write unsafe code to do a bitwise copy so that i could use SyncWrapper's If anybody happens to stumble upon this, you should know that sqlx is an alternative and happens to implement Sync. This is not to downplay the library owner's work (especially since this library has its own upsides), but its certainly a better solution then using SyncWrapper. |
Sync
trait requirementsSync
traits for some structsChanges allow to use async_trait_with_sync (allowed returning
Client
andJoinHandle
)