Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(enginenetx): make LookupTactics async #1300

Merged
merged 9 commits into from
Sep 25, 2023
Merged

Conversation

bassosimone
Copy link
Contributor

@bassosimone bassosimone commented Sep 25, 2023

Rather than waiting for LookupTactics to complete, make it async and let it stream the tactics back to the caller. This design allows us to start connecting while DNS lookups are still in progress when we have configured beacons for specific hosts. In turn, this means we could perform more operations in the same unit of time, by overalapping some DNS lookups and TCP+TLS dials. Additionally, the new design would also work quite well with a DNS resolver that awaits for additional responses after the first one and returns all of them as tactics.

While there, recognize that the HTTPSDialer code and the code in the related structs was a bit more complex than it should be. We don't need to explicitly honor the context when moving data between goroutines as long as the writer goroutines write until completion and then close the channel, and as long as reader goroutines read until either the channel is closed (when there's a single writer) or all the possible writers have completed (otherwise). Networking code and networking-like code is the only code that MAY block and for which we really need a context.

With the new simplified design, all the goroutines will join before DialTLSContext returns, hence we don't need anymore a sync.WaitGroup to make sure we're not leaking any goroutine in this code.

Part of ooni/probe#2531

Rather than waiting for LookupTactics to complete, make it async and
let it stream the tactics back to the caller. This design allows us to
start connection while DNS lookups are still in progress when we have
configured beacons for specific hosts. In turn, this means we could
perform more operations in the same unit of time, by overallapping some
operations. Additionally, the new design would also work quite well
with a DNS resolver that awaits for additional responses after the first.

While there, recognize that the HTTPSDialer code and the code in the
related structs was a bit more complex than it could. This diff rewrites
code to mostly pass the context around and only honour it in network-like
operations (e.g., when waiting to be ready, performing DNS lookup, TCP
dialing, or TLS handshaking). The rest of the infrastructure around the
code that performs network operations always assumes to read channels
until completion and to emit all the possible events. So, readers will
read as much as they can and writes will write as much as they can
but canceling the context will cause network operations to be interrupted
and hence the reporting of many errors.

Part of ooni/probe#2531
@bassosimone bassosimone merged commit 1af54cf into master Sep 25, 2023
8 checks passed
@bassosimone bassosimone deleted the issue/2531-small branch September 25, 2023 19:49
Murphy-OrangeMud pushed a commit to Murphy-OrangeMud/probe-cli that referenced this pull request Feb 13, 2024
Rather than waiting for LookupTactics to complete, make it async and let
it stream the tactics back to the caller. This design allows us to start
connecting while DNS lookups are still in progress when we have
configured beacons for specific hosts. In turn, this means we could
perform more operations in the same unit of time, by overalapping some
DNS lookups and TCP+TLS dials. Additionally, the new design would also
work quite well with a DNS resolver that awaits for additional responses
after the first one and returns all of them as tactics.

While there, recognize that the HTTPSDialer code and the code in the
related structs was a bit more complex than it should be. We don't need
to explicitly honor the context when moving data between goroutines as
long as the writer goroutines write until completion and then close the
channel, and as long as reader goroutines read until either the channel
is closed (when there's a single writer) or all the possible writers
have completed (otherwise). Networking code and networking-like code is
the only code that MAY block and for which we really need a context.

With the new simplified design, all the goroutines will join before
`DialTLSContext` returns, hence we don't need anymore a `sync.WaitGroup`
to make sure we're not leaking any goroutine in this code.

Part of ooni/probe#2531
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant