From f7bc0aced8bcc6d8ac5daa729807eb4214099a5c Mon Sep 17 00:00:00 2001 From: 0xff-dev Date: Sun, 8 Oct 2023 15:45:20 +0800 Subject: [PATCH] fix: goroutine leak --- api/go.mod | 1 + api/go.sum | 2 ++ api/internal/utils/timedcall.go | 2 +- api/internal/utils/timedcall_test.go | 18 ++++++++++++++++++ 4 files changed, 22 insertions(+), 1 deletion(-) diff --git a/api/go.mod b/api/go.mod index 3cbe563554..de6a78e083 100644 --- a/api/go.mod +++ b/api/go.mod @@ -7,6 +7,7 @@ require ( github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 github.com/imdario/mergo v0.3.13 github.com/stretchr/testify v1.8.1 + go.uber.org/goleak v1.3.0 gopkg.in/evanphx/json-patch.v5 v5.6.0 gopkg.in/yaml.v2 v2.4.0 k8s.io/kube-openapi v0.0.0-20230601164746-7562a1006961 diff --git a/api/go.sum b/api/go.sum index 7330eccd85..1159652388 100644 --- a/api/go.sum +++ b/api/go.sum @@ -61,6 +61,8 @@ github.com/xlab/treeprint v1.2.0 h1:HzHnuAF1plUN2zGlAFHbSQP2qJ0ZAD3XF5XD7OesXRQ= github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0= go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 h1:+FNtrFTmVw0YZGpBGX56XDee331t6JAXeK2bcyhLOOc= go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5/go.mod h1:nmDLcffg48OtT/PSW0Hg7FvpRQsQh5OSqIylirxKC7o= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= golang.org/x/sys v0.0.0-20191002063906-3421d5a6bb1c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= diff --git a/api/internal/utils/timedcall.go b/api/internal/utils/timedcall.go index 0afadd0c3f..cda53f864b 100644 --- a/api/internal/utils/timedcall.go +++ b/api/internal/utils/timedcall.go @@ -10,7 +10,7 @@ import ( // TimedCall runs fn, failing if it doesn't complete in the given duration. // The description is used in the timeout error message. func TimedCall(description string, d time.Duration, fn func() error) error { - done := make(chan error) + done := make(chan error, 1) timer := time.NewTimer(d) defer timer.Stop() go func() { done <- fn() }() diff --git a/api/internal/utils/timedcall_test.go b/api/internal/utils/timedcall_test.go index 192edc48cd..d805806eed 100644 --- a/api/internal/utils/timedcall_test.go +++ b/api/internal/utils/timedcall_test.go @@ -9,6 +9,7 @@ import ( "time" "github.com/stretchr/testify/assert" + "go.uber.org/goleak" . "sigs.k8s.io/kustomize/api/internal/utils" ) @@ -62,3 +63,20 @@ func TestTimedCallSlowWithError(t *testing.T) { t.Fail() } } + +func TestTimedCallGoroutineLeak(t *testing.T) { + defer goleak.VerifyNone(t) + err := TimedCall("function done, no goroutine leaks", timeToWait, func() error { + time.Sleep(tooSlow) + return fmt.Errorf("function done") + }) + if assert.Error(t, err) { + assert.EqualError(t, err, errMsg("function done, no goroutine leaks")) + } else { + t.Fail() + } + + // The code introduces a 2-second sleep to allow the goroutine to complete its execution. + // Subsequently, it verifies if the goroutine created by the function exits as expected. + time.Sleep(tooSlow) +}