Stream: wg-async-foundations

Topic: Is this Future impl sound?

weiznich (Aug 06 2019 at 17:52, on Zulip):

Hi there,

I've played a bit with implementing a async database interface for diesel. There is basically one big issue that currently blocks this:
Futures returned by async fn(and by using -> impl Future ) leak Send/Sync bounds. Database connections are by design Send but not Sync. Normal functions interacting with the database now take a &Connection. As soon as you do this in a async function the returned future will contain shared references to those connection. This results in making the returned Future !Send because a shared reference of a !Sync type is !Send. One way to work around this issue is to use mutable references to the Connection everywhere, but that makes it hard to construct a nice API, especially something like a transaction function that takes a closure and internally manages all the transaction state (like calling "Beging"/"Commit"/"Abort") on the provided transaction in the right positions. (For the long version of the problem see this diesel issue which has various playground links that demonstrate different approaches which all fail due to complicated life time stuff. Additionally there is this playground playground from Nemo157 which demonstrates that something like that is possible at the cost of disallowing closures (which is not so great from a API point of view…))

So I played again a bit with this and came up with the this solution, but I'm unsure if that is even sound (Especially the unsafe stuff at line 85-89 erasing some lifetimes). It should be impossible (because of the 'static bound on R that the resolved async closure returns something that contains a reference to the connection passed to the closure. Additionally only poll is called till this future is resolved, so in theory no leak should be possible.

(Sorry if that's the wrong place to ask this kind of question, but I'm not sure where it belongs to.)

Last update: Jul 16 2020 at 15:15UTC