Skip to content

Commit 094e3a5

Browse files
committed
Made the gRPC daemon actually wait for port close completion
1 parent f2a023a commit 094e3a5

File tree

3 files changed

+17
-4
lines changed

3 files changed

+17
-4
lines changed

commands/daemon/daemon.go

+15-2
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"errors"
2121
"fmt"
2222
"io"
23+
"sync/atomic"
2324

2425
"github.com/arduino/arduino-cli/commands"
2526
"github.com/arduino/arduino-cli/commands/board"
@@ -490,6 +491,10 @@ func (s *ArduinoCoreServerImpl) Monitor(stream rpc.ArduinoCoreService_MonitorSer
490491
_ = syncSend.Send(&rpc.MonitorResponse{Success: true})
491492

492493
cancelCtx, cancel := context.WithCancel(stream.Context())
494+
gracefulCloseInitiated := &atomic.Bool{}
495+
gracefuleCloseCtx, gracefulCloseCancel := context.WithCancel(context.Background())
496+
497+
// gRPC stream receiver (gRPC data -> monitor, config, close)
493498
go func() {
494499
defer cancel()
495500
for {
@@ -509,9 +514,11 @@ func (s *ArduinoCoreServerImpl) Monitor(stream rpc.ArduinoCoreService_MonitorSer
509514
}
510515
}
511516
if closeMsg := msg.GetClose(); closeMsg {
517+
gracefulCloseInitiated.Store(true)
512518
if err := portProxy.Close(); err != nil {
513519
logrus.WithError(err).Debug("Error closing monitor port")
514520
}
521+
gracefulCloseCancel()
515522
}
516523
tx := msg.GetTxData()
517524
for len(tx) > 0 {
@@ -528,8 +535,9 @@ func (s *ArduinoCoreServerImpl) Monitor(stream rpc.ArduinoCoreService_MonitorSer
528535
}
529536
}()
530537

538+
// gRPC stream sender (monitor -> gRPC)
531539
go func() {
532-
defer cancel()
540+
defer cancel() // unlock the receiver
533541
buff := make([]byte, 4096)
534542
for {
535543
n, err := portProxy.Read(buff)
@@ -547,6 +555,11 @@ func (s *ArduinoCoreServerImpl) Monitor(stream rpc.ArduinoCoreService_MonitorSer
547555
}()
548556

549557
<-cancelCtx.Done()
550-
portProxy.Close()
558+
if gracefulCloseInitiated.Load() {
559+
// Port closing has been initiated in the receiver
560+
<-gracefuleCloseCtx.Done()
561+
} else {
562+
portProxy.Close()
563+
}
551564
return nil
552565
}

internal/integrationtest/monitor/monitor_grpc_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ func TestMonitorGRPCClose(t *testing.T) {
8282
}
8383

8484
// Now close the monitor using MonitorRequest_Close
85-
for tries := 0; tries < 5; tries++ { // Try the test 5 times to avoid flukes
85+
{
8686
// Keep a timeout to allow the test to exit in any case
8787
ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
8888
mon, err := grpcInst.Monitor(ctx, ports[0].Port)

internal/mock_serial_monitor/main.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ func (d *SerialMonitor) Close() error {
197197
d.mockedSerialPort.Close()
198198
d.openedPort = false
199199
if d.muxFile != nil {
200-
time.Sleep(500 * time.Millisecond) // Emulate a small delay closing the port to check gRPC synchronization
200+
time.Sleep(2000 * time.Millisecond) // Emulate a small delay closing the port to check gRPC synchronization
201201
d.muxFile.Remove()
202202
d.muxFile = nil
203203
}

0 commit comments

Comments
 (0)