[WIP] [PoC] '&' -> '&mut'
#777
Rascunho
jebrosen quer aplicar o merge de 2 commits de igalic/go/async-all-mut
em go/async
pull de: igalic/go/async-all-mut
merge em: Plume:go/async
Plume:paginate-search-init
Plume:main
Plume:s3
Plume:fix-delete-user
Plume:timeline-cli
Plume:blog-title
Plume:signature
Plume:remove-dup-images
Plume:ldap-non-anon
Plume:drone-ci
Plume:DearRude/force-lang
Plume:go/async
Plume:floreal/translations-update
Plume:missing-docs
Plume:RAOF/fix-arm64-build
Plume:epsilon-phase/authorized-fetch
Plume:upgrade
Plume:improve-the-editor-once-again
Plume:igalic/feat/custom-fairing-domains
Plume:feature/ldap
Plume:test/dotenv_error
Plume:fix-mobile-margin
Revisores
Solicitar revisão
Sem revisor
Etiquetas
Limpar etiquetas
Related to the REST API
Code running on the server
Stuff related to Federation
Related to the front-end
Translations, and related code
More about project management or code than the project itself
The building, or installation process of Plume
Something isn't working
We need to talk
New feature or request
This is a new feature
Compatibility with different browsers, readers and OS
Related to an external package that Plume uses
UI/UX related issues and PRs
Good for newcomers
Extra attention is needed
Issues affecting only mobile UX
How elements're rendered out for the end user
Something else needs to be fixed first
This issue or pull request already exists
This PR is not complete yet
Issues concern a limited number of instances
This doesn't seem right
Need to be discussed by the community (on Loomio)
This PR is ready to be reviewed
Proposed ideas worth considering
This is issue has been created after a vote on Loomio
This will not be worked on
Aplicar etiquetas
A: API
Related to the REST API
A: Backend
Code running on the server
A: Federation
Stuff related to Federation
A: Front-End
Related to the front-end
A: I18N
Translations, and related code
A: Meta
More about project management or code than the project itself
A: Security
Build
The building, or installation process of Plume
C: Bug
Something isn't working
C: Discussion
We need to talk
C: Enhancement
New feature or request
C: Feature
This is a new feature
Compatibility
Compatibility with different browsers, readers and OS
Dependency
Related to an external package that Plume uses
Design
UI/UX related issues and PRs
Documentation
Good first issue
Good for newcomers
Help welcome
Extra attention is needed
Mobile
Issues affecting only mobile UX
Rendering
How elements're rendered out for the end user
S: Blocked
Something else needs to be fixed first
S: Duplicate
This issue or pull request already exists
S: Incomplete
This PR is not complete yet
S: Instance specific
Issues concern a limited number of instances
S: Invalid
This doesn't seem right
S: Needs Voting/Discussion
Need to be discussed by the community (on Loomio)
S: Ready for review
This PR is ready to be reviewed
Suggestion
Proposed ideas worth considering
S: Voted on Loomio
This is issue has been created after a vote on Loomio
S: Wontfix
This will not be worked on
Sem etiqueta
A: API
A: Backend
A: Federation
A: Front-End
A: I18N
A: Meta
A: Security
Build
C: Bug
C: Discussion
C: Enhancement
C: Feature
Compatibility
Dependency
Design
Documentation
Good first issue
Help welcome
Mobile
Rendering
S: Blocked
S: Duplicate
S: Incomplete
S: Instance specific
S: Invalid
S: Needs Voting/Discussion
S: Ready for review
Suggestion
S: Voted on Loomio
S: Wontfix
Marco
Definir marco
Limpar marco
Nenhum item
Sem marco
Responsáveis
Atribuir usuários
Limpar responsáveis
Sem responsável
2 participante(s)
Notificações
Data limite
A data limite é inválida ou está fora do intervalo. Por favor, use o formato 'dd/mm/aaaa'.
Data limite não informada.
Dependências
Nenhuma dependência definida.
Referência: Plume/Plume#777
Referência em uma nova issue
Ainda não há conteúdo.
Excluir Branch 'igalic/go/async-all-mut'
A exclusão de um branch é permanente. Isto NÃO PODERÁ ser desfeito. Continuar?
Não
Sim
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.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.
This is basically how actors work (like in Erlang and derivative, or the Actix lib for Rust), it would allow to keep
&
, would properly handle blocking operation out of async context, and maybe allow to compile both Postgresql and Sqlite in the same binary (however this would also be a lot of work, not that much new code, but lots of moving things around)Yeah, I think that's more or less the direction I was going with "wrap
Connection
with an API likeconn.run(|c| Post::load(&c)).await
". I agree that it's a nicer overall solution, with the biggest drawback being:🤷♀️
we have come this far, we might as well do it right.
Passo 1:
No repositório do seu projeto, crie um novo branch e teste as alterações.Passo 2:
Faça merge das alterações e atualize no Forgejo.