From 4932ba78ff15845866ce6c292180ab76279d8554 Mon Sep 17 00:00:00 2001 From: Kyle Carberry Date: Fri, 18 Feb 2022 16:45:55 +0000 Subject: [PATCH 1/3] fix: Leaking yamux session after HTTP handler is closed Closes #317. We depended on the context canceling the yamux connection, but this isn't a sync operation. Explicitly calling close ensures the handler waits for yamux to complete before exit. --- coderd/provisionerdaemons.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/coderd/provisionerdaemons.go b/coderd/provisionerdaemons.go index a75730dc0a876..91503cba8cec5 100644 --- a/coderd/provisionerdaemons.go +++ b/coderd/provisionerdaemons.go @@ -84,6 +84,9 @@ func (api *api) provisionerDaemonsServe(rw http.ResponseWriter, r *http.Request) _ = conn.Close(websocket.StatusInternalError, fmt.Sprintf("multiplex server: %s", err)) return } + defer func() { + _ = session.Close() + }() mux := drpcmux.New() err = proto.DRPCRegisterProvisionerDaemon(mux, &provisionerdServer{ ID: daemon.ID, From 5601b4d9da160928ef91f81006fd04252ea0d996 Mon Sep 17 00:00:00 2001 From: Kyle Carberry Date: Fri, 18 Feb 2022 17:02:18 +0000 Subject: [PATCH 2/3] Lock around close return --- provisionerd/provisionerd.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/provisionerd/provisionerd.go b/provisionerd/provisionerd.go index 4c438d7360f66..b8449a38fbb05 100644 --- a/provisionerd/provisionerd.go +++ b/provisionerd/provisionerd.go @@ -110,10 +110,13 @@ func (p *provisionerDaemon) connect(ctx context.Context) { if errors.Is(err, context.Canceled) { return } + p.closeMutex.Lock() if p.isClosed() { + p.closeMutex.Unlock() return } p.opts.Logger.Warn(context.Background(), "failed to dial", slog.Error(err)) + p.closeMutex.Unlock() continue } p.opts.Logger.Debug(context.Background(), "connected") From 055ce11347d5e1300cdd4d3c7202afcee89a3a09 Mon Sep 17 00:00:00 2001 From: Kyle Carberry Date: Fri, 18 Feb 2022 19:45:04 +0000 Subject: [PATCH 3/3] Force failure with log --- .github/workflows/coder.yaml | 8 +++++--- coderd/coderdtest/coderdtest.go | 4 ++-- coderd/provisionerdaemons.go | 5 +++-- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/.github/workflows/coder.yaml b/.github/workflows/coder.yaml index f75fee6d7aa5f..d821943c66b63 100644 --- a/.github/workflows/coder.yaml +++ b/.github/workflows/coder.yaml @@ -150,9 +150,11 @@ jobs: terraform_wrapper: false - name: Test with Mock Database + env: + GOMAXPROCS: ${{ runner.os == 'Windows' && 1 || 2 }} run: gotestsum --junitfile="gotests.xml" --packages="./..." -- - -covermode=atomic -coverprofile="gotests.coverage" - -timeout=3m -count=5 -race -short -parallel=2 + -covermode=atomic -coverprofile="gotests.coverage" -failfast + -timeout=3m -count=5 -race -short - name: Upload DataDog Trace if: (success() || failure()) && github.actor != 'dependabot[bot]' @@ -166,7 +168,7 @@ jobs: if: runner.os == 'Linux' run: DB=true gotestsum --junitfile="gotests.xml" --packages="./..." -- -covermode=atomic -coverprofile="gotests.coverage" -timeout=3m - -count=1 -race -parallel=2 + -count=1 -race -parallel=2 -failfast - name: Upload DataDog Trace if: (success() || failure()) && github.actor != 'dependabot[bot]' diff --git a/coderd/coderdtest/coderdtest.go b/coderd/coderdtest/coderdtest.go index dc7f782c83748..2ecd367803b48 100644 --- a/coderd/coderdtest/coderdtest.go +++ b/coderd/coderdtest/coderdtest.go @@ -157,7 +157,7 @@ func AwaitProjectImportJob(t *testing.T, client *codersdk.Client, organization s provisionerJob, err = client.ProjectImportJob(context.Background(), organization, job) require.NoError(t, err) return provisionerJob.Status.Completed() - }, 3*time.Second, 25*time.Millisecond) + }, 5*time.Second, 25*time.Millisecond) return provisionerJob } @@ -169,7 +169,7 @@ func AwaitWorkspaceProvisionJob(t *testing.T, client *codersdk.Client, organizat provisionerJob, err = client.WorkspaceProvisionJob(context.Background(), organization, job) require.NoError(t, err) return provisionerJob.Status.Completed() - }, 3*time.Second, 25*time.Millisecond) + }, 5*time.Second, 25*time.Millisecond) return provisionerJob } diff --git a/coderd/provisionerdaemons.go b/coderd/provisionerdaemons.go index 91503cba8cec5..83c22da7d6a3a 100644 --- a/coderd/provisionerdaemons.go +++ b/coderd/provisionerdaemons.go @@ -84,8 +84,9 @@ func (api *api) provisionerDaemonsServe(rw http.ResponseWriter, r *http.Request) _ = conn.Close(websocket.StatusInternalError, fmt.Sprintf("multiplex server: %s", err)) return } - defer func() { - _ = session.Close() + go func() { + <-r.Context().Done() + _, _ = fmt.Printf("\n\n\n\nDONE\n\n\n\n") }() mux := drpcmux.New() err = proto.DRPCRegisterProvisionerDaemon(mux, &provisionerdServer{