[WIP] [PoC] '&' -> '&mut'#777
[WIP] [PoC] '&' -> '&mut'#777jebrosen wants to merge 2 commits intoPlume-org:go/asyncfrom igalic:go/async-all-mut
Conversation
Key changes:
* `find plume-models -name '*.rs' -exec sed -i -e 's/&PlumeRocket/\&mut PlumeRocket/' '{}' \;`
* Remove `let conn = &*rockets.conn;` lines
* Change `conn` to `&mut *rockets.conn` where `conn` was used
|
I think the best way to handle sql connections would be to have worker threads that are basically dedicated to that, and have a mpsc channel through which requests can be send to them, alongside a one shot channel that allow to return a result. |
Yeah, I think that's more or less the direction I was going with "wrap
|
🤷♀️ we have come this far, we might as well do it right. |
This is a (incomplete) proof of concept of a possible workaround for
Syncissues that appear inasynccode.Roughly, the issue is this:
Send. This requirement comes from Rocket, and would be nontrivial and/or undesirable to change in Rocket.&PlumeRocketor an&Connectionheld across anawaitpoint&PlumeRocket/&Connectionmust beSend&T: SendiffT: Sync, soPlumeRocket/Connectionmust beSyncPlumeRocketcontains aConnection, andConnectioncontains a dieselPgConnection, which is notSync.The approach demonstrated here is to change every
&PlumeRocketor&Connectionto an&mut PlumeRocketor&mut Connection.&mut TisSendifTisSend, so the problem is eliminated:Send.&mut PlumeRocketor an&mut Connectionheld across anawaitpoint&mut PlumeRocket/&mut Connectionmust beSend&mut T: SendiffT: Send, soPlumeRocket/Connectionmust beSendPlumeRocketcontains aConnection, andConnectioncontains a dieselPgConnection, which isSend.Downsides
&PlumeRocketcould 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.FromIdandInbox. 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!&->&mutchange. A different solution that keeps&in more places would be easier to work with overall.asyncfns, which can cause issues ranging from degraded performance to deadlocks.Alternatives
Mutexaround theConnectionsomewhere. Uncontended mutexes (which this one should be) are not a huge performance concern, butMutexmay be at least as or more unwieldy than this solution throughout the code.Connectionwith an API likeconn.run(|c| Post::load(&c)).await, whererunhandles 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.