Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This is a (incomplete) proof of concept of a possible workaround for
Sync
issues that appear inasync
code.Roughly, the issue is this:
Send
. This requirement comes from Rocket, and would be nontrivial and/or undesirable to change in Rocket.&PlumeRocket
or an&Connection
held across anawait
point&PlumeRocket
/&Connection
must beSend
&T: Send
iffT: Sync
, soPlumeRocket
/Connection
must beSync
PlumeRocket
contains aConnection
, andConnection
contains a dieselPgConnection
, which is notSync
.The approach demonstrated here is to change every
&PlumeRocket
or&Connection
to an&mut PlumeRocket
or&mut Connection
.&mut T
isSend
ifT
isSend
, so the problem is eliminated:Send
.&mut PlumeRocket
or an&mut Connection
held across anawait
point&mut PlumeRocket
/&mut Connection
must beSend
&mut T: Send
iffT: Send
, soPlumeRocket
/Connection
must beSend
PlumeRocket
contains aConnection
, andConnection
contains a dieselPgConnection
, which isSend
.Downsides
&PlumeRocket
could allow more work to be done in parallel, at least in the future. It does not look like that is currently the case, since every call to the database blocks anyway.FromId
andInbox
. I know relatively little about the overall structure of this code, so this could be incorrect or inconvenient in ways I don't know about!&
->&mut
change. A different solution that keeps&
in more places would be easier to work with overall.async
fns, which can cause issues ranging from degraded performance to deadlocks.Alternatives
Mutex
around theConnection
somewhere. Uncontended mutexes (which this one should be) are not a huge performance concern, butMutex
may be at least as or more unwieldy than this solution throughout the code.Connection
with an API likeconn.run(|c| Post::load(&c)).await
, whererun
handles the synchronization. This has similar tradeoffs to aMutex
, is probably the most inconvenient option in terms of overall code changes, and is also a significant chunk of new code to write and debug. However, it has the advantage of being capable of fixing the blocking-in-async
-fn problem.