Skip to content

client: Increase the min connect timeout from 1s to 3s (otherwise connecting to distant Engines fails)#8328

Merged
gerhard merged 2 commits intodagger:mainfrom
neutronth:client/set-less-aggressive-minimum-connect-timeout-for-buildkit
Sep 9, 2024
Merged

client: Increase the min connect timeout from 1s to 3s (otherwise connecting to distant Engines fails)#8328
gerhard merged 2 commits intodagger:mainfrom
neutronth:client/set-less-aggressive-minimum-connect-timeout-for-buildkit

Conversation

@neutronth
Copy link
Copy Markdown
Contributor

* The MinConnectTimeout was set to 1s which is good for a fast
  recovering from the situation that the engine is not ready to accept
  connections, while at the same time, it's too aggressive for a remote
  engine, eg. Dagger Engine on a Kubernetes [1], the engine may not complete
  the connect phase within the deadline and always failed in the
  connection checking loop [2].

  Until the buildkit implements the better way of client creation [3],
  increase the timeout with a less aggressive 3s could mitigate this issue.

  [1] https://docs.dagger.io/integrations/kubernetes
  [2] https://github.com/dagger/dagger/blob/main/engine/client/buildkit.go#L45
  [3] https://github.com/grpc/grpc-go/blob/master/Documentation/anti-patterns.md

Signed-off-by: Neutron Soutmun <neutron.s@linecorp.com>
@jedevc
Copy link
Copy Markdown
Contributor

jedevc commented Sep 4, 2024

This was originally lowered from the default 20s in #7612 (cc @marcosnils).

I'm a bit worried now if 3s is enough, but bringing it up too high negatively effects retry rates.

Genuinely such a pain to manage this, see a previous case of trying to resolve this in buildkit: moby/buildkit#4200.

Until the buildkit implements the better way of client creation [3], increase the timeout with a less aggressive 3s could mitigate this issue.

That's definitely something we could do (not right now, but sometime).

@jedevc jedevc requested a review from marcosnils September 4, 2024 08:41
@gerhard
Copy link
Copy Markdown
Contributor

gerhard commented Sep 4, 2024

Not being able to establish a connection within 1s does seem problematic. What makes the delay so high @neutronth in your environment?

Before this change, we had:

  • 1s (MinConnectTimeout)
  • 1.2s
  • 2.4s
  • 4.8s
  • 9.6s
  • 19.2s
  • 30s (capped by MaxDelay)
  • 30s (subsequent attempts)

After this change as it stands, the reconnect attempts will become:

  • 3s (MinConnectTimeout)
  • 3s (MinConnectTimeout)
  • 3s (MinConnectTimeout)
  • 4.8s
  • 9.6s
  • 19.2s
  • 30s (capped by MaxDelay)
  • 30s (subsequent attempts)

More frequent initial attempts - i.e. 2s - seems like a good compromise:

  • 2s (MinConnectTimeout)
  • 2s (MinConnectTimeout)
  • 2.4s
  • 4.8s
  • 9.6s
  • 19.2s
  • 30s (capped by MaxDelay)
  • 30s (subsequent attempts)

The above makes me wonder if we should set the MaxDelay to 10s, so that we would end with:

  • 2s (MinConnectTimeout)
  • 2s (MinConnectTimeout)
  • 2.4s
  • 4.8s
  • 9.6s
  • 10s (capped by MaxDelay)
  • 10s (subsequent attempts)

Would the above work for your environment @neutronth? WDYT @jedevc @marcosnils?

As a different approach, I quiet like the idea of picking a default of 2s & 10s max, and also allowing this to be configurable.

@wingyplus
Copy link
Copy Markdown
Contributor

also allowing this to be configurable.

I’m interesting to tackle on this one if you all are ok. Currently @neutronth and I need to adjust in Dagger source and rebuild the cli manually. :(

@neutronth
Copy link
Copy Markdown
Contributor Author

@gerhard my environment is a development one that Dagger CLI connects to remote engine hosted in remote cloud Kubernetes cluster (oversea network), more latency added, I guess.

The Dagger CLI established the buildkit client over the kubepod [1] connection helper, it's been established properly.
However, it could not connect to the engine.

First of all, I was also wondering why it behaves like that as I saw the back-off configuration and it should be tackled properly.
From the debug log, I found that the client try to get the engine information with INFO call as shown in the log below:

09:45:43 DBG recording span span="dagger --progress=plain --debug core container" id=63d7cb911591c282                       09:46:06 [117/41903]
09:45:43 DBG recording span span=connect id=8057150ed7455027
09:45:43 DBG recording span child span=connect parent=63d7cb911591c282 child=8057150ed7455027
09:45:43 DBG recording span span="starting engine" id=b375c496da631526
09:45:43 DBG recording span child span="starting engine" parent=8057150ed7455027 child=b375c496da631526
09:45:43 DBG new end old="1754-08-31 05:25:45.128654848 +0642 LMT" new="2024-09-05 09:45:43.143629417 +0700 +07"
09:45:43 DBG recording span span="starting engine" id=b375c496da631526
09:45:43 DBG recording span child span="starting engine" parent=8057150ed7455027 child=b375c496da631526
09:45:43 DBG recording span span="connecting to engine" id=4c17aba9b59f85d2
09:45:43 DBG recording span child span="connecting to engine" parent=8057150ed7455027 child=4c17aba9b59f85d2
...
...
09:45:43 DBG recording span span=moby.buildkit.v1.Control/Info id=6a01b9c33e282582
...
09:45:44 DBG recording span span=moby.buildkit.v1.Control/Info id=6a01b9c33e282582
...
09:45:45 DBG recording span span=moby.buildkit.v1.Control/Info id=958aba786e46f9d9
...
09:45:46 DBG recording span span=moby.buildkit.v1.Control/Info id=09502a0e524f6ad3
...
09:45:47 DBG recording span span=moby.buildkit.v1.Control/Info id=f91f898b1622f66b
...
...
...

The spans have been splited with 1s and not looked like a back-off retrying.
Refers to @jedevc mentioned PR [2], it clearly explains why this behavior occured,
the client.Wait() overrides the back-off setting of gRPC connection option and retry every 1s instead.
Therefore, the expected back-off never applied to this case.

  • 1s (MinConnectTimeout) -> no response -> wait for 1s
  • 1s (MinConnectTimeout) -> no response -> wait for 1s
  • 1s (MinConnectTimeout) -> no response -> wait for 1s
  • ...
  • ...
  • Until 10mins deadline wihtout success

Hence, this PR try to mitigate this issue by give the client more chance to succeed (in my case, 3s does)


[1] https://github.com/moby/buildkit/blob/master/client/connhelper/kubepod/kubepod.go
[2] moby/buildkit#4200

@jedevc
Copy link
Copy Markdown
Contributor

jedevc commented Sep 5, 2024

Yeah, the reason for this logic in buildkit is because we want a fast response for if the server is still in the starting state - the client should not back off, because it's a server side failure. This logic still applies for our use case.

However, yeah, this isn't great. But I've never been able to work out a good compromise that works well both for local (low-latency, so this kind of waiting is alright) and remote (higher-latency, so backoff is needed).

  • Perhaps we actually want to have two different behaviors for those two cases?
  • Potentially, we can just call grpc's WaitForReady option? The issue is, because that does exponential backoff, we can get poor performance with the common local case.
  • Potentially we should implement a separate side-channel of health checks into the docker driver? So we can see when the engine comes up, then using WaitForReady should be fine?
    • Something like checking to see if /run/buildkit/buildkitd.sock exists could work.

All of those feel like better long-term solutions to me, but I'm potentially still alright with this as a short term solution.

@gerhard
Copy link
Copy Markdown
Contributor

gerhard commented Sep 9, 2024

@neutronth that makes sense. Happy to go ahead with this as a short-term solution, and follow-up with a more robust implementation, as @jedevc mentioned.

Getting this approved & merged so that it can be released in the upcoming v0.13.0. Would you be OK to follow-up a more robust implementation that would work longer-term @neutronth?

Looking forward to your configurable follow-up @wingyplus 💪

@gerhard gerhard added this to the v0.13.0 milestone Sep 9, 2024
@gerhard gerhard added the needs/changelog Pull requests that require a changelog entry label Sep 9, 2024
@gerhard
Copy link
Copy Markdown
Contributor

gerhard commented Sep 9, 2024

Going to add a relese notes fragment before approving & merging. FTR: https://docs.dagger.io/contributing/#3-add-release-notes-fragment

Copy link
Copy Markdown
Contributor

@gerhard gerhard left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 💪 🚀

@gerhard gerhard merged commit e899b5a into dagger:main Sep 9, 2024
@gerhard gerhard changed the title client: set less aggressive minimum connect timeout for buildkit client: Increase the min connect timeout from 1s to 3s (otherwise connecting to distant Engines fails) Sep 9, 2024
@wingyplus
Copy link
Copy Markdown
Contributor

Thank you @gerhard.

Looking forward to your configurable follow-up @wingyplus 💪

I will submit a PR in 2-3 days. 💪

scottames referenced this pull request in scottames/dots Sep 25, 2024
This PR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [dagger/dagger](https://redirect.github.com/dagger/dagger) | minor |
`v0.12.7` -> `v0.13.0` |

---

### Release Notes

<details>
<summary>dagger/dagger (dagger/dagger)</summary>

###
[`v0.13.0`](https://redirect.github.com/dagger/dagger/blob/HEAD/CHANGELOG.md#v0130---2024-09-11)

[Compare
Source](https://redirect.github.com/dagger/dagger/compare/v0.12.7...v0.13.0)

##### 🔥 Breaking Changes

- Remove deprecated fields and arguments by
[@&#8203;jedevc](https://redirect.github.com/jedevc) in
[https://github.com/dagger/dagger/pull/8065](https://redirect.github.com/dagger/dagger/pull/8065)
- Remove `Container.withExec`'s `skipEntrypoint` argument - this is now
the default (see `useEntrypoint`)
    -   Remove `pipeline`, `Container.pipeline` and `Directory.pipeline`
- Remove `GitModuleSource.cloneURL` (see `GitModuleSource.cloneRef`)

##### Added

- Added new `Directory.digest` and `ModuleSource.digest` fields by
[@&#8203;jedevc](https://redirect.github.com/jedevc) in
[https://github.com/dagger/dagger/pull/8282](https://redirect.github.com/dagger/dagger/pull/8282)
\
These fields mirror the behavior of the `File.digest` field, computing a
    unique cryptographic digest over the contents of the object.
- TUI: add `--no-exit`/`-E` so you can poke around after the call
completes by [@&#8203;vito](https://redirect.github.com/vito) in
[https://github.com/dagger/dagger/pull/8389](https://redirect.github.com/dagger/dagger/pull/8389)

##### Changed

- The trace url is printed just before the final output to make it easy
to find by
[@&#8203;rajatjindal](https://redirect.github.com/rajatjindal) in
[https://github.com/dagger/dagger/pull/8366](https://redirect.github.com/dagger/dagger/pull/8366)
\
Also, the url will be printed only for a subset of dagger commands to
reduce noise.
- Increase the minimum connect timeout from 1s to 3s by
[@&#8203;neutronth](https://redirect.github.com/neutronth) in
[https://github.com/dagger/dagger/pull/8328](https://redirect.github.com/dagger/dagger/pull/8328)
\
Connecting to a distant remote engine could otherwise fail if it was not
reachable in 1s.

##### Fixed

- Fixed void types from core incorrectly being seen as named scalars by
[@&#8203;helderco](https://redirect.github.com/helderco) in
[https://github.com/dagger/dagger/pull/8336](https://redirect.github.com/dagger/dagger/pull/8336)
- Fix setting secrets on module object in constructor by
[@&#8203;sipsma](https://redirect.github.com/sipsma) in
[https://github.com/dagger/dagger/pull/8149](https://redirect.github.com/dagger/dagger/pull/8149)
- Allow top-level field access with no constructor by
[@&#8203;jedevc](https://redirect.github.com/jedevc) in
[https://github.com/dagger/dagger/pull/8331](https://redirect.github.com/dagger/dagger/pull/8331)
\
Previously, if a field access was made immediately after the default
constructor was called, then the access would fail.
- Plain progress correctly displays carriage returns by
[@&#8203;jedevc](https://redirect.github.com/jedevc) in
[https://github.com/dagger/dagger/pull/8347](https://redirect.github.com/dagger/dagger/pull/8347)
\
Carriage returns could previously render weirdly in the output,
displaying empty lines, and similar visual glitches.
- cli: Fix default value on `Platform` flag by
[@&#8203;helderco](https://redirect.github.com/helderco) in
[https://github.com/dagger/dagger/pull/8360](https://redirect.github.com/dagger/dagger/pull/8360)

##### What to do next?

-   Read the [documentation](https://docs.dagger.io)
-   Join our [Discord server](https://discord.gg/dagger-io)
-   Follow us on [Twitter](https://twitter.com/dagger_io)

</details>

---

### Configuration

📅 **Schedule**: Branch creation - "after 4pm on thursday" in timezone
America/Los_Angeles, Automerge - At any time (no schedule defined).

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/scottames/dots).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOC43NC4xIiwidXBkYXRlZEluVmVyIjoiMzguNzQuMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiZGVwZW5kZW5jaWVzIl19-->

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: scottames-github-bot[bot] <162828115+scottames-github-bot[bot]@users.noreply.github.com>
scottames referenced this pull request in scottames/containers Sep 25, 2024
This PR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [dagger/dagger](https://redirect.github.com/dagger/dagger) | minor |
`v0.12.7` -> `v0.13.0` |

---

### Release Notes

<details>
<summary>dagger/dagger (dagger/dagger)</summary>

###
[`v0.13.0`](https://redirect.github.com/dagger/dagger/blob/HEAD/CHANGELOG.md#v0130---2024-09-11)

[Compare
Source](https://redirect.github.com/dagger/dagger/compare/v0.12.7...v0.13.0)

##### 🔥 Breaking Changes

- Remove deprecated fields and arguments by
[@&#8203;jedevc](https://redirect.github.com/jedevc) in
[https://github.com/dagger/dagger/pull/8065](https://redirect.github.com/dagger/dagger/pull/8065)
- Remove `Container.withExec`'s `skipEntrypoint` argument - this is now
the default (see `useEntrypoint`)
    -   Remove `pipeline`, `Container.pipeline` and `Directory.pipeline`
- Remove `GitModuleSource.cloneURL` (see `GitModuleSource.cloneRef`)

##### Added

- Added new `Directory.digest` and `ModuleSource.digest` fields by
[@&#8203;jedevc](https://redirect.github.com/jedevc) in
[https://github.com/dagger/dagger/pull/8282](https://redirect.github.com/dagger/dagger/pull/8282)
\
These fields mirror the behavior of the `File.digest` field, computing a
    unique cryptographic digest over the contents of the object.
- TUI: add `--no-exit`/`-E` so you can poke around after the call
completes by [@&#8203;vito](https://redirect.github.com/vito) in
[https://github.com/dagger/dagger/pull/8389](https://redirect.github.com/dagger/dagger/pull/8389)

##### Changed

- The trace url is printed just before the final output to make it easy
to find by
[@&#8203;rajatjindal](https://redirect.github.com/rajatjindal) in
[https://github.com/dagger/dagger/pull/8366](https://redirect.github.com/dagger/dagger/pull/8366)
\
Also, the url will be printed only for a subset of dagger commands to
reduce noise.
- Increase the minimum connect timeout from 1s to 3s by
[@&#8203;neutronth](https://redirect.github.com/neutronth) in
[https://github.com/dagger/dagger/pull/8328](https://redirect.github.com/dagger/dagger/pull/8328)
\
Connecting to a distant remote engine could otherwise fail if it was not
reachable in 1s.

##### Fixed

- Fixed void types from core incorrectly being seen as named scalars by
[@&#8203;helderco](https://redirect.github.com/helderco) in
[https://github.com/dagger/dagger/pull/8336](https://redirect.github.com/dagger/dagger/pull/8336)
- Fix setting secrets on module object in constructor by
[@&#8203;sipsma](https://redirect.github.com/sipsma) in
[https://github.com/dagger/dagger/pull/8149](https://redirect.github.com/dagger/dagger/pull/8149)
- Allow top-level field access with no constructor by
[@&#8203;jedevc](https://redirect.github.com/jedevc) in
[https://github.com/dagger/dagger/pull/8331](https://redirect.github.com/dagger/dagger/pull/8331)
\
Previously, if a field access was made immediately after the default
constructor was called, then the access would fail.
- Plain progress correctly displays carriage returns by
[@&#8203;jedevc](https://redirect.github.com/jedevc) in
[https://github.com/dagger/dagger/pull/8347](https://redirect.github.com/dagger/dagger/pull/8347)
\
Carriage returns could previously render weirdly in the output,
displaying empty lines, and similar visual glitches.
- cli: Fix default value on `Platform` flag by
[@&#8203;helderco](https://redirect.github.com/helderco) in
[https://github.com/dagger/dagger/pull/8360](https://redirect.github.com/dagger/dagger/pull/8360)

##### What to do next?

-   Read the [documentation](https://docs.dagger.io)
-   Join our [Discord server](https://discord.gg/dagger-io)
-   Follow us on [Twitter](https://twitter.com/dagger_io)

</details>

---

### Configuration

📅 **Schedule**: Branch creation - "after 4pm on thursday" in timezone
America/Los_Angeles, Automerge - At any time (no schedule defined).

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/scottames/containers).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOC43NC4xIiwidXBkYXRlZEluVmVyIjoiMzguNzQuMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiZGVwZW5kZW5jaWVzIl19-->

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: scottames-github-bot[bot] <162828115+scottames-github-bot[bot]@users.noreply.github.com>
scottames referenced this pull request in scottames/daggerverse Sep 25, 2024
This PR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [dagger/dagger](https://redirect.github.com/dagger/dagger) | minor |
`v0.12.7` -> `v0.13.0` |

---

### Release Notes

<details>
<summary>dagger/dagger (dagger/dagger)</summary>

###
[`v0.13.0`](https://redirect.github.com/dagger/dagger/blob/HEAD/CHANGELOG.md#v0130---2024-09-11)

[Compare
Source](https://redirect.github.com/dagger/dagger/compare/v0.12.7...v0.13.0)

##### 🔥 Breaking Changes

- Remove deprecated fields and arguments by
[@&#8203;jedevc](https://redirect.github.com/jedevc) in
[https://github.com/dagger/dagger/pull/8065](https://redirect.github.com/dagger/dagger/pull/8065)
- Remove `Container.withExec`'s `skipEntrypoint` argument - this is now
the default (see `useEntrypoint`)
    -   Remove `pipeline`, `Container.pipeline` and `Directory.pipeline`
- Remove `GitModuleSource.cloneURL` (see `GitModuleSource.cloneRef`)

##### Added

- Added new `Directory.digest` and `ModuleSource.digest` fields by
[@&#8203;jedevc](https://redirect.github.com/jedevc) in
[https://github.com/dagger/dagger/pull/8282](https://redirect.github.com/dagger/dagger/pull/8282)
\
These fields mirror the behavior of the `File.digest` field, computing a
    unique cryptographic digest over the contents of the object.
- TUI: add `--no-exit`/`-E` so you can poke around after the call
completes by [@&#8203;vito](https://redirect.github.com/vito) in
[https://github.com/dagger/dagger/pull/8389](https://redirect.github.com/dagger/dagger/pull/8389)

##### Changed

- The trace url is printed just before the final output to make it easy
to find by
[@&#8203;rajatjindal](https://redirect.github.com/rajatjindal) in
[https://github.com/dagger/dagger/pull/8366](https://redirect.github.com/dagger/dagger/pull/8366)
\
Also, the url will be printed only for a subset of dagger commands to
reduce noise.
- Increase the minimum connect timeout from 1s to 3s by
[@&#8203;neutronth](https://redirect.github.com/neutronth) in
[https://github.com/dagger/dagger/pull/8328](https://redirect.github.com/dagger/dagger/pull/8328)
\
Connecting to a distant remote engine could otherwise fail if it was not
reachable in 1s.

##### Fixed

- Fixed void types from core incorrectly being seen as named scalars by
[@&#8203;helderco](https://redirect.github.com/helderco) in
[https://github.com/dagger/dagger/pull/8336](https://redirect.github.com/dagger/dagger/pull/8336)
- Fix setting secrets on module object in constructor by
[@&#8203;sipsma](https://redirect.github.com/sipsma) in
[https://github.com/dagger/dagger/pull/8149](https://redirect.github.com/dagger/dagger/pull/8149)
- Allow top-level field access with no constructor by
[@&#8203;jedevc](https://redirect.github.com/jedevc) in
[https://github.com/dagger/dagger/pull/8331](https://redirect.github.com/dagger/dagger/pull/8331)
\
Previously, if a field access was made immediately after the default
constructor was called, then the access would fail.
- Plain progress correctly displays carriage returns by
[@&#8203;jedevc](https://redirect.github.com/jedevc) in
[https://github.com/dagger/dagger/pull/8347](https://redirect.github.com/dagger/dagger/pull/8347)
\
Carriage returns could previously render weirdly in the output,
displaying empty lines, and similar visual glitches.
- cli: Fix default value on `Platform` flag by
[@&#8203;helderco](https://redirect.github.com/helderco) in
[https://github.com/dagger/dagger/pull/8360](https://redirect.github.com/dagger/dagger/pull/8360)

##### What to do next?

-   Read the [documentation](https://docs.dagger.io)
-   Join our [Discord server](https://discord.gg/dagger-io)
-   Follow us on [Twitter](https://twitter.com/dagger_io)

</details>

---

### Configuration

📅 **Schedule**: Branch creation - "after 4pm on thursday" in timezone
America/Los_Angeles, Automerge - At any time (no schedule defined).

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/scottames/daggerverse).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOC43NC4xIiwidXBkYXRlZEluVmVyIjoiMzguNzQuMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiZGVwZW5kZW5jaWVzIl19-->

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: scottames-github-bot[bot] <162828115+scottames-github-bot[bot]@users.noreply.github.com>
Co-authored-by: Scott Ames <scott@ames.sh>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs/changelog Pull requests that require a changelog entry

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants