Skip to content

Commit 2d33dec

Browse files
committed
Made the gRPC daemon actually wait for port close completion
1 parent 7dc60f3 commit 2d33dec

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/arduino"
2526
"github.com/arduino/arduino-cli/commands"
@@ -451,6 +452,10 @@ func (s *ArduinoCoreServerImpl) Monitor(stream rpc.ArduinoCoreService_MonitorSer
451452
_ = syncSend.Send(&rpc.MonitorResponse{Success: true})
452453

453454
cancelCtx, cancel := context.WithCancel(stream.Context())
455+
gracefulCloseInitiated := &atomic.Bool{}
456+
gracefuleCloseCtx, gracefulCloseCancel := context.WithCancel(context.Background())
457+
458+
// gRPC stream receiver (gRPC data -> monitor, config, close)
454459
go func() {
455460
defer cancel()
456461
for {
@@ -470,9 +475,11 @@ func (s *ArduinoCoreServerImpl) Monitor(stream rpc.ArduinoCoreService_MonitorSer
470475
}
471476
}
472477
if closeMsg := msg.GetClose(); closeMsg {
478+
gracefulCloseInitiated.Store(true)
473479
if err := portProxy.Close(); err != nil {
474480
logrus.WithError(err).Debug("Error closing monitor port")
475481
}
482+
gracefulCloseCancel()
476483
}
477484
tx := msg.GetTxData()
478485
for len(tx) > 0 {
@@ -489,8 +496,9 @@ func (s *ArduinoCoreServerImpl) Monitor(stream rpc.ArduinoCoreService_MonitorSer
489496
}
490497
}()
491498

499+
// gRPC stream sender (monitor -> gRPC)
492500
go func() {
493-
defer cancel()
501+
defer cancel() // unlock the receiver
494502
buff := make([]byte, 4096)
495503
for {
496504
n, err := portProxy.Read(buff)
@@ -508,6 +516,11 @@ func (s *ArduinoCoreServerImpl) Monitor(stream rpc.ArduinoCoreService_MonitorSer
508516
}()
509517

510518
<-cancelCtx.Done()
511-
portProxy.Close()
519+
if gracefulCloseInitiated.Load() {
520+
// Port closing has been initiated in the receiver
521+
<-gracefuleCloseCtx.Done()
522+
} else {
523+
portProxy.Close()
524+
}
512525
return nil
513526
}

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)