瀏覽代碼

avoid goroutine leak after timeout (#575)

Kevin Wan 4 年之前
父節點
當前提交
9e6c2ba2c0

+ 2 - 2
core/fx/timeout.go

@@ -26,7 +26,8 @@ func DoWithTimeout(fn func() error, timeout time.Duration, opts ...DoOption) err
 	ctx, cancel := contextx.ShrinkDeadline(parentCtx, timeout)
 	defer cancel()
 
-	done := make(chan error)
+	// create channel with buffer size 1 to avoid goroutine leak
+	done := make(chan error, 1)
 	panicChan := make(chan interface{}, 1)
 	go func() {
 		defer func() {
@@ -35,7 +36,6 @@ func DoWithTimeout(fn func() error, timeout time.Duration, opts ...DoOption) err
 			}
 		}()
 		done <- fn()
-		close(done)
 	}()
 
 	select {

+ 2 - 2
zrpc/internal/clientinterceptors/timeoutinterceptor.go

@@ -19,7 +19,8 @@ func TimeoutInterceptor(timeout time.Duration) grpc.UnaryClientInterceptor {
 		ctx, cancel := contextx.ShrinkDeadline(ctx, timeout)
 		defer cancel()
 
-		done := make(chan error)
+		// create channel with buffer size 1 to avoid goroutine leak
+		done := make(chan error, 1)
 		panicChan := make(chan interface{}, 1)
 		go func() {
 			defer func() {
@@ -29,7 +30,6 @@ func TimeoutInterceptor(timeout time.Duration) grpc.UnaryClientInterceptor {
 			}()
 
 			done <- invoker(ctx, method, req, reply, cc, opts...)
-			close(done)
 		}()
 
 		select {

+ 1 - 0
zrpc/internal/serverinterceptors/timeoutinterceptor.go

@@ -20,6 +20,7 @@ func UnaryTimeoutInterceptor(timeout time.Duration) grpc.UnaryServerInterceptor
 		var err error
 		var lock sync.Mutex
 		done := make(chan struct{})
+		// create channel with buffer size 1 to avoid goroutine leak
 		panicChan := make(chan interface{}, 1)
 		go func() {
 			defer func() {