refactor(p2p): use async/await syntax on peer discovery #883
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.
Motivation
While studying for another project, I found out that our version of Twisted actually supports using the
async/await
python syntax, and even recommends it (docs):This has multiple benefits, improving readability, static type checking, and may even boost performance, according to the docs above.
We should aim to gradually convert this code, where it makes sense. Mostly, it makes sense to convert it everywhere the
@inlineCallbacks
decorator is used, as the conversion is pretty straightforward. Places using directDeferred
callback manipulation require a bit more thought so we may not want to convert them. Ideally, new could should always use the new syntax.Here's a small cheat sheet for conversion:
@inlineCallbacks
toasync
andyield
toawait
(Deferred
s areAwaitable
). Also, change the return type fromGenerator[_, _, T]
toT
.Deferred
s are eager (they start running as soon as they're created) while coroutines (async
functions) are lazy (they start running when they're awaited). This means that currently we have places in code where synchronous code ("non-inlineCallbacks
") create aDeferred
without any callbacks, so the behavior is "fire and forget". Since coroutines cannot be awaited in "non-async" functions, we need to useDeferred.fromCoroutine()
in order to convert and automatically make them run.It is my understanding that we could have only a single
Deferred.fromCoroutine()
in the code, in the outermost async function, and all subsequent usages could leverage theasync/await
syntax directly. This is currently not possible because of those "fire and forget" cases. They may indicate that we should explicitly handle those deferred's callbacks, improving robustness (since they're currently ignored), and then they could be converted toasync/await
s too. That would bubble up async functions all the way to the startup of our code. This is a larger refactor and we could do it incrementally.Acceptance Criteria
@inlineCallbacks/yield
functions and methods related to peer discovery to useasync/await
instead. Also, update return types accordingly.HathorProtocol
andBaseState
to accept coroutines as commands.ConnectionsManager
to fire and forget a coroutine.Checklist
master
, confirm this code is production-ready and can be included in future releases as soon as it gets merged