Skip to content

Commit 9ac1235

Browse files
tune deployment operator service reconciliation
1 parent c87c2e6 commit 9ac1235

3 files changed

Lines changed: 61 additions & 3 deletions

File tree

.cursor/skills/console-tests/SKILL.md

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
name: console-tests
3-
description: Run and interpret tests in the Console Elixir repo. Use when validating changes with `mix test`, running Docker integration tests, diagnosing sandbox network failures, or explaining Console test setup in Cursor.
3+
description: Run and interpret tests in the Console repo. Use when validating changes with `mix test`, running deployment-operator Go tests, diagnosing sandbox/toolchain/network failures, or explaining Console test setup in Cursor.
44
---
55

66
# Console Tests
@@ -10,8 +10,19 @@ Use this skill when validating changes in the Console repo.
1010
## Sandbox Requirements
1111

1212
- Run `mix test` commands from the repo root: `/Users/michaelguarino/code/console`.
13+
- Run deployment-operator Go commands from `/Users/michaelguarino/code/console/go/deployment-operator`.
1314
- The default Cursor sandbox blocks some domains the Console app touches during startup and test aliases.
1415
- Use `required_permissions: ["full_network"]` for `mix test` runs that need the normal project setup.
16+
- For Go tests, explicitly set Go caches inside the workspace when running in the sandbox:
17+
18+
```bash
19+
cd /Users/michaelguarino/code/console/go/deployment-operator && \
20+
GOPATH=/Users/michaelguarino/code/console/.go \
21+
GOCACHE=/Users/michaelguarino/code/console/.cache/go-build \
22+
go test ./pkg/controller/service
23+
```
24+
25+
- Use `required_permissions: ["full_network"]` for Go tests when dependencies or the configured Go toolchain need to download. If Go still fails writing to `/Users/michaelguarino/go/pkg/...`, rerun with the in-workspace `GOPATH`/`GOCACHE` above before requesting `all`.
1526
- Do not run `mix format` in this repository.
1627

1728
## Why Full Network Is Needed
@@ -38,16 +49,36 @@ Full suite:
3849
mix test
3950
```
4051

52+
Focused deployment-operator service package:
53+
54+
```bash
55+
cd /Users/michaelguarino/code/console/go/deployment-operator && \
56+
GOPATH=/Users/michaelguarino/code/console/.go \
57+
GOCACHE=/Users/michaelguarino/code/console/.cache/go-build \
58+
go test ./pkg/controller/service
59+
```
60+
61+
Format changed deployment-operator Go files:
62+
63+
```bash
64+
cd /Users/michaelguarino/code/console/go/deployment-operator && \
65+
gofmt -w pkg/controller/service/reconciler.go pkg/manifests/tarball.go
66+
```
67+
4168

4269
## Interpreting Failures
4370

4471
- A focused test passing is good validation for narrow changes, especially when the full suite is known to depend on external/local fixtures.
4572
- Full-suite failures like `could not resolve ref main` or `could not resolve ref master` usually indicate git fixture/ref setup problems unless the touched code is in that path.
73+
- Go failures like `go.work requires go >= 1.26.5` can mean the IDE/linter is using an older local Go. A shell `go test` may still work through Go's auto toolchain download when network and cache permissions are set correctly.
74+
- Sandbox errors writing under `/Users/michaelguarino/go/pkg/sumdb` indicate the Go module/toolchain cache is outside the writable workspace. Prefer setting `GOPATH` and `GOCACHE` inside `/Users/michaelguarino/code/console`.
4675
- Report full-suite failures honestly, but separate environment/fixture failures from failures in the files being changed.
4776

4877
## Validation Checklist
4978

5079
- [ ] Run the most relevant focused test file with `full_network` if it uses project startup or external services.
80+
- [ ] For deployment-operator Go changes, run `gofmt -w` on touched files from the module directory.
81+
- [ ] For deployment-operator Go tests, `cd` into `go/deployment-operator` and use in-workspace `GOPATH`/`GOCACHE` when sandboxed.
5182
- [ ] Run the full suite with `full_network` when requested or when the change has broad impact.
5283
- [ ] Read the final ExUnit summary and any failure blocks for touched modules.
5384
- [ ] Run `ReadLints` on changed files after edits.

go/deployment-operator/pkg/controller/service/reconciler.go

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"errors"
66
"fmt"
7+
"net"
78
"net/http"
89
"strings"
910
"time"
@@ -387,7 +388,7 @@ func (s *ServiceReconciler) Poll(ctx context.Context) error {
387388
logger.V(4).Info("enqueueing update for", "service", svc.Node.ID)
388389
s.svcCache.Add(svc.Node.ID, svc.Node)
389390
currentServices.Add(svc.Node.Name)
390-
s.svcQueue.AddAfter(svc.Node.ID, utils.Jitter(15*time.Second))
391+
s.svcQueue.AddAfter(svc.Node.ID, utils.Jitter(s.pollJitterWindow()))
391392
}
392393
}
393394

@@ -489,6 +490,10 @@ func (s *ServiceReconciler) Reconcile(ctx context.Context, id string) (result re
489490
dir, err := s.manifestCache.Fetch(svc)
490491
if err != nil {
491492
logger.Error(err, "failed to parse manifests", "service", svc.Name)
493+
if isTransientFetchError(err) {
494+
done = true
495+
return ctrl.Result{}, nil
496+
}
492497
if isExpectedError(err) {
493498
// mark as the expected error so that it won't get propagated to the API as a service error
494499
err = plrlerrors.ErrExpected
@@ -615,3 +620,25 @@ func isExpectedError(err error) bool {
615620
}
616621
return false
617622
}
623+
624+
func isRateLimitError(err error) bool {
625+
var httpErr *manis.HTTPError
626+
return errors.As(err, &httpErr) && httpErr.StatusCode == http.StatusTooManyRequests
627+
}
628+
629+
func isTimeoutError(err error) bool {
630+
var netErr net.Error
631+
return errors.As(err, &netErr) && netErr.Timeout()
632+
}
633+
634+
func isTransientFetchError(err error) bool {
635+
return isRateLimitError(err) || isTimeoutError(err)
636+
}
637+
638+
func (s *ServiceReconciler) pollJitterWindow() time.Duration {
639+
interval := s.GetPollInterval()()
640+
if interval <= 0 {
641+
return 15 * time.Second
642+
}
643+
return interval / 2
644+
}

go/deployment-operator/pkg/manifests/tarball.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import (
1414
const pluralDigestHeader = "x-plrl-digest"
1515

1616
var (
17-
timeout = 60 * time.Second
17+
timeout = 10 * time.Second
1818
client = &http.Client{
1919
Timeout: timeout,
2020
Transport: &http.Transport{

0 commit comments

Comments
 (0)