Skip to content

Commit 2d8a623

Browse files
committed
rpc: guard grpc status stream send w/ mutex
gRPC has a fun quirk where if you call SendMsg on the same stream in parallel from multiple goroutines, you can easily hit a deadlock in some internal grpc writeQuota thing: grpc/grpc-go#5393 (comment) Was hitting some random deadlocks in dagger and saw from SIGQUIT stacks that we were blocked on that writeQuota call. Wrapping the WriteStatus implementation in a mutex fixed it. Signed-off-by: Erik Sipsma <erik@sipsma.dev>
1 parent 140ccef commit 2d8a623

File tree

1 file changed

+4
-0
lines changed

1 file changed

+4
-0
lines changed

rpc.go

+4
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"errors"
66
"io"
77
"net"
8+
"sync"
89

910
grpc "google.golang.org/grpc"
1011
"google.golang.org/grpc/credentials/insecure"
@@ -47,6 +48,7 @@ func DialRPC(ctx context.Context, target string) (Writer, error) {
4748
type RPCWriter struct {
4849
Conn *grpc.ClientConn
4950
Updates ProgressService_WriteUpdatesClient
51+
l sync.Mutex
5052
}
5153

5254
// NewRPCWriter returns a new RPCWriter.
@@ -59,6 +61,8 @@ func NewRPCWriter(conn *grpc.ClientConn, updates ProgressService_WriteUpdatesCli
5961

6062
// WriteStatus implements Writer.
6163
func (w *RPCWriter) WriteStatus(status *StatusUpdate) error {
64+
w.l.Lock()
65+
defer w.l.Unlock()
6266
return w.Updates.Send(status)
6367
}
6468

0 commit comments

Comments
 (0)