From 32de5ed395734d9c621dbc2fcf92fcf53d3cb2a0 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Fri, 5 May 2023 17:56:47 +0200 Subject: [PATCH 1/3] Added integration test --- internal/integrationtest/arduino-cli.go | 5 +- .../daemon/daemon_concurrency_test.go | 76 + .../integrationtest/daemon/daemon_test.go | 6 +- .../ManyWarningsSketch/ManyWarningsSketch.ino | 2502 +++++++++++++++++ 4 files changed, 2584 insertions(+), 5 deletions(-) create mode 100644 internal/integrationtest/daemon/daemon_concurrency_test.go create mode 100644 internal/integrationtest/testdata/ManyWarningsSketch/ManyWarningsSketch.ino diff --git a/internal/integrationtest/arduino-cli.go b/internal/integrationtest/arduino-cli.go index efbe717b02b..6df85c7a1ff 100644 --- a/internal/integrationtest/arduino-cli.go +++ b/internal/integrationtest/arduino-cli.go @@ -388,14 +388,15 @@ func (inst *ArduinoCLIInstance) PlatformInstall(ctx context.Context, packager, a } // Compile calls the "Compile" gRPC method. -func (inst *ArduinoCLIInstance) Compile(ctx context.Context, fqbn, sketchPath string) (commands.ArduinoCoreService_CompileClient, error) { +func (inst *ArduinoCLIInstance) Compile(ctx context.Context, fqbn, sketchPath string, warnings string) (commands.ArduinoCoreService_CompileClient, error) { compileCl, err := inst.cli.daemonClient.Compile(ctx, &commands.CompileRequest{ Instance: inst.instance, Fqbn: fqbn, SketchPath: sketchPath, Verbose: true, + Warnings: warnings, }) - logCallf(">>> Compile(%v %v)\n", fqbn, sketchPath) + logCallf(">>> Compile(%v %v warnings=%v)\n", fqbn, sketchPath, warnings) return compileCl, err } diff --git a/internal/integrationtest/daemon/daemon_concurrency_test.go b/internal/integrationtest/daemon/daemon_concurrency_test.go new file mode 100644 index 00000000000..acde5b97341 --- /dev/null +++ b/internal/integrationtest/daemon/daemon_concurrency_test.go @@ -0,0 +1,76 @@ +// This file is part of arduino-cli. +// +// Copyright 2022 ARDUINO SA (http://www.arduino.cc/) +// +// This software is released under the GNU General Public License version 3, +// which covers the main part of arduino-cli. +// The terms of this license can be found at: +// https://www.gnu.org/licenses/gpl-3.0.en.html +// +// You can be released from the requirements of the above licenses by purchasing +// a commercial license. Buying such a license is mandatory if you want to +// modify or otherwise use the software for commercial activities involving the +// Arduino software without disclosing the source code of your own applications. +// To purchase a commercial license, send an email to license@arduino.cc. + +package daemon_test + +import ( + "context" + "fmt" + "io" + "testing" + "time" + + "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" + "github.com/arduino/go-paths-helper" + "github.com/stretchr/testify/require" +) + +func TestArduinoCliDaemonCompileWithLotOfOutput(t *testing.T) { + // See: https://github.com/arduino/arduino-cli/issues/2169 + + env, cli := createEnvForDaemon(t) + defer env.CleanUp() + + _, _, err := cli.Run("core", "install", "arduino:avr") + require.NoError(t, err) + + grpcInst := cli.Create() + require.NoError(t, grpcInst.Init("", "", func(ir *commands.InitResponse) { + fmt.Printf("INIT> %v\n", ir.GetMessage()) + })) + + sketchPath, err := paths.New("..", "testdata", "ManyWarningsSketch").Abs() + require.NoError(t, err) + + testCompile := func() { + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + compile, err := grpcInst.Compile(ctx, "arduino:avr:uno", sketchPath.String(), "all") + require.NoError(t, err) + msgCount := 0 + for { + _, err := compile.Recv() + if err == io.EOF { + break + } + msgCount++ + require.NoError(t, err) + } + fmt.Println("Received", msgCount, "messages.") + } + + // The synchronization bug doesn't always happens, try 10 times to + // increase the chance to trigger it. + testCompile() + testCompile() + testCompile() + testCompile() + testCompile() + testCompile() + testCompile() + testCompile() + testCompile() + testCompile() +} diff --git a/internal/integrationtest/daemon/daemon_test.go b/internal/integrationtest/daemon/daemon_test.go index e49636bd69a..45967c0b23a 100644 --- a/internal/integrationtest/daemon/daemon_test.go +++ b/internal/integrationtest/daemon/daemon_test.go @@ -135,7 +135,7 @@ func TestDaemonCompileOptions(t *testing.T) { // Build sketch (with errors) sk := paths.New("testdata", "bare_minimum") - compile, err := grpcInst.Compile(context.Background(), "arduino:avr:uno:some_menu=bad", sk.String()) + compile, err := grpcInst.Compile(context.Background(), "arduino:avr:uno:some_menu=bad", sk.String(), "") require.NoError(t, err) for { msg, err := compile.Recv() @@ -153,7 +153,7 @@ func TestDaemonCompileOptions(t *testing.T) { } // Build sketch (without errors) - compile, err = grpcInst.Compile(context.Background(), "arduino:avr:uno:some_menu=good", sk.String()) + compile, err = grpcInst.Compile(context.Background(), "arduino:avr:uno:some_menu=good", sk.String(), "") require.NoError(t, err) for { msg, err := compile.Recv() @@ -180,7 +180,7 @@ func TestDaemonCompileAfterFailedLibInstall(t *testing.T) { // Build sketch (with errors) sk := paths.New("testdata", "bare_minimum") - compile, err := grpcInst.Compile(context.Background(), "", sk.String()) + compile, err := grpcInst.Compile(context.Background(), "", sk.String(), "") require.NoError(t, err) for { msg, err := compile.Recv() diff --git a/internal/integrationtest/testdata/ManyWarningsSketch/ManyWarningsSketch.ino b/internal/integrationtest/testdata/ManyWarningsSketch/ManyWarningsSketch.ino new file mode 100644 index 00000000000..d4382a2bc2c --- /dev/null +++ b/internal/integrationtest/testdata/ManyWarningsSketch/ManyWarningsSketch.ino @@ -0,0 +1,2502 @@ +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +#warning foo +void setup() {} +void loop() {} From cc5ea1904309fd5e45b2734717b224ca87fb165d Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Fri, 5 May 2023 17:57:22 +0200 Subject: [PATCH 2/3] Apply stream-send synchronization in Compile grpc call --- commands/daemon/daemon.go | 9 +++++---- commands/daemon/stream.go | 23 +++++++++++++++++++++++ 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/commands/daemon/daemon.go b/commands/daemon/daemon.go index bb62bc137db..70b4b973854 100644 --- a/commands/daemon/daemon.go +++ b/commands/daemon/daemon.go @@ -202,16 +202,17 @@ func (s *ArduinoCoreServerImpl) LoadSketch(ctx context.Context, req *rpc.LoadSke // Compile FIXMEDOC func (s *ArduinoCoreServerImpl) Compile(req *rpc.CompileRequest, stream rpc.ArduinoCoreService_CompileServer) error { - outStream := feedStreamTo(func(data []byte) { stream.Send(&rpc.CompileResponse{OutStream: data}) }) - errStream := feedStreamTo(func(data []byte) { stream.Send(&rpc.CompileResponse{ErrStream: data}) }) + syncSend := NewSynchronizedSend(stream.Send) + outStream := feedStreamTo(func(data []byte) { syncSend.Send(&rpc.CompileResponse{OutStream: data}) }) + errStream := feedStreamTo(func(data []byte) { syncSend.Send(&rpc.CompileResponse{ErrStream: data}) }) compileResp, compileErr := compile.Compile( stream.Context(), req, outStream, errStream, - func(p *rpc.TaskProgress) { stream.Send(&rpc.CompileResponse{Progress: p}) }) + func(p *rpc.TaskProgress) { syncSend.Send(&rpc.CompileResponse{Progress: p}) }) outStream.Close() errStream.Close() var compileRespSendErr error if compileResp != nil { - compileRespSendErr = stream.Send(compileResp) + compileRespSendErr = syncSend.Send(compileResp) } if compileErr != nil { return convertErrorToRPCStatus(compileErr) diff --git a/commands/daemon/stream.go b/commands/daemon/stream.go index d0c321e484f..87fb213c761 100644 --- a/commands/daemon/stream.go +++ b/commands/daemon/stream.go @@ -98,3 +98,26 @@ func consumeStreamFrom(reader func() ([]byte, error)) io.Reader { }() return r } + +// SynchronizedSender is a sender function with an extra protection for +// concurrent writes, if multiple threads call the Send method they will +// be blocked and serialized. +type SynchronizedSender[T any] struct { + lock sync.Mutex + protectedSend func(T) error +} + +// Send the message using the underlyng stream. +func (s *SynchronizedSender[T]) Send(value T) error { + s.lock.Lock() + err := s.protectedSend(value) + s.lock.Unlock() + return err +} + +// NewSynchronizedSend takes a Send function and wraps it in a SynchronizedSender +func NewSynchronizedSend[T any](send func(T) error) *SynchronizedSender[T] { + return &SynchronizedSender[T]{ + protectedSend: send, + } +} From e6da5f852b392b4b45403f2fffcb1604186b26d9 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Fri, 5 May 2023 18:03:12 +0200 Subject: [PATCH 3/3] Apply the same pattern to all daemon gRPC calls --- commands/daemon/daemon.go | 100 ++++++++++++++++++++++---------------- 1 file changed, 59 insertions(+), 41 deletions(-) diff --git a/commands/daemon/daemon.go b/commands/daemon/daemon.go index 70b4b973854..748e7bfaf6a 100644 --- a/commands/daemon/daemon.go +++ b/commands/daemon/daemon.go @@ -87,6 +87,7 @@ func (s *ArduinoCoreServerImpl) BoardSearch(ctx context.Context, req *rpc.BoardS // BoardListWatch FIXMEDOC func (s *ArduinoCoreServerImpl) BoardListWatch(stream rpc.ArduinoCoreService_BoardListWatchServer) error { + syncSend := NewSynchronizedSend(stream.Send) msg, err := stream.Recv() if err == io.EOF { return nil @@ -97,7 +98,7 @@ func (s *ArduinoCoreServerImpl) BoardListWatch(stream rpc.ArduinoCoreService_Boa if msg.Instance == nil { err = fmt.Errorf(tr("no instance specified")) - stream.Send(&rpc.BoardListWatchResponse{ + syncSend.Send(&rpc.BoardListWatchResponse{ EventType: "error", Error: err.Error(), }) @@ -132,7 +133,7 @@ func (s *ArduinoCoreServerImpl) BoardListWatch(stream rpc.ArduinoCoreService_Boa }() for event := range eventsChan { - if err := stream.Send(event); err != nil { + if err := syncSend.Send(event); err != nil { logrus.Infof("sending board watch message: %v", err) } } @@ -148,16 +149,18 @@ func (s *ArduinoCoreServerImpl) Destroy(ctx context.Context, req *rpc.DestroyReq // UpdateIndex FIXMEDOC func (s *ArduinoCoreServerImpl) UpdateIndex(req *rpc.UpdateIndexRequest, stream rpc.ArduinoCoreService_UpdateIndexServer) error { + syncSend := NewSynchronizedSend(stream.Send) err := commands.UpdateIndex(stream.Context(), req, - func(p *rpc.DownloadProgress) { stream.Send(&rpc.UpdateIndexResponse{DownloadProgress: p}) }, + func(p *rpc.DownloadProgress) { syncSend.Send(&rpc.UpdateIndexResponse{DownloadProgress: p}) }, ) return convertErrorToRPCStatus(err) } // UpdateLibrariesIndex FIXMEDOC func (s *ArduinoCoreServerImpl) UpdateLibrariesIndex(req *rpc.UpdateLibrariesIndexRequest, stream rpc.ArduinoCoreService_UpdateLibrariesIndexServer) error { + syncSend := NewSynchronizedSend(stream.Send) err := commands.UpdateLibrariesIndex(stream.Context(), req, - func(p *rpc.DownloadProgress) { stream.Send(&rpc.UpdateLibrariesIndexResponse{DownloadProgress: p}) }, + func(p *rpc.DownloadProgress) { syncSend.Send(&rpc.UpdateLibrariesIndexResponse{DownloadProgress: p}) }, ) return convertErrorToRPCStatus(err) } @@ -177,9 +180,8 @@ func (s *ArduinoCoreServerImpl) Create(ctx context.Context, req *rpc.CreateReque // Init FIXMEDOC func (s *ArduinoCoreServerImpl) Init(req *rpc.InitRequest, stream rpc.ArduinoCoreService_InitServer) error { - err := commands.Init(req, func(message *rpc.InitResponse) { - stream.Send(message) - }) + syncSend := NewSynchronizedSend(stream.Send) + err := commands.Init(req, func(message *rpc.InitResponse) { syncSend.Send(message) }) return convertErrorToRPCStatus(err) } @@ -222,52 +224,56 @@ func (s *ArduinoCoreServerImpl) Compile(req *rpc.CompileRequest, stream rpc.Ardu // PlatformInstall FIXMEDOC func (s *ArduinoCoreServerImpl) PlatformInstall(req *rpc.PlatformInstallRequest, stream rpc.ArduinoCoreService_PlatformInstallServer) error { + syncSend := NewSynchronizedSend(stream.Send) resp, err := core.PlatformInstall( stream.Context(), req, - func(p *rpc.DownloadProgress) { stream.Send(&rpc.PlatformInstallResponse{Progress: p}) }, - func(p *rpc.TaskProgress) { stream.Send(&rpc.PlatformInstallResponse{TaskProgress: p}) }, + func(p *rpc.DownloadProgress) { syncSend.Send(&rpc.PlatformInstallResponse{Progress: p}) }, + func(p *rpc.TaskProgress) { syncSend.Send(&rpc.PlatformInstallResponse{TaskProgress: p}) }, ) if err != nil { return convertErrorToRPCStatus(err) } - return stream.Send(resp) + return syncSend.Send(resp) } // PlatformDownload FIXMEDOC func (s *ArduinoCoreServerImpl) PlatformDownload(req *rpc.PlatformDownloadRequest, stream rpc.ArduinoCoreService_PlatformDownloadServer) error { + syncSend := NewSynchronizedSend(stream.Send) resp, err := core.PlatformDownload( stream.Context(), req, - func(p *rpc.DownloadProgress) { stream.Send(&rpc.PlatformDownloadResponse{Progress: p}) }, + func(p *rpc.DownloadProgress) { syncSend.Send(&rpc.PlatformDownloadResponse{Progress: p}) }, ) if err != nil { return convertErrorToRPCStatus(err) } - return stream.Send(resp) + return syncSend.Send(resp) } // PlatformUninstall FIXMEDOC func (s *ArduinoCoreServerImpl) PlatformUninstall(req *rpc.PlatformUninstallRequest, stream rpc.ArduinoCoreService_PlatformUninstallServer) error { + syncSend := NewSynchronizedSend(stream.Send) resp, err := core.PlatformUninstall( stream.Context(), req, - func(p *rpc.TaskProgress) { stream.Send(&rpc.PlatformUninstallResponse{TaskProgress: p}) }, + func(p *rpc.TaskProgress) { syncSend.Send(&rpc.PlatformUninstallResponse{TaskProgress: p}) }, ) if err != nil { return convertErrorToRPCStatus(err) } - return stream.Send(resp) + return syncSend.Send(resp) } // PlatformUpgrade FIXMEDOC func (s *ArduinoCoreServerImpl) PlatformUpgrade(req *rpc.PlatformUpgradeRequest, stream rpc.ArduinoCoreService_PlatformUpgradeServer) error { + syncSend := NewSynchronizedSend(stream.Send) resp, err := core.PlatformUpgrade( stream.Context(), req, - func(p *rpc.DownloadProgress) { stream.Send(&rpc.PlatformUpgradeResponse{Progress: p}) }, - func(p *rpc.TaskProgress) { stream.Send(&rpc.PlatformUpgradeResponse{TaskProgress: p}) }, + func(p *rpc.DownloadProgress) { syncSend.Send(&rpc.PlatformUpgradeResponse{Progress: p}) }, + func(p *rpc.TaskProgress) { syncSend.Send(&rpc.PlatformUpgradeResponse{TaskProgress: p}) }, ) if err != nil { return convertErrorToRPCStatus(err) } - return stream.Send(resp) + return syncSend.Send(resp) } // PlatformSearch FIXMEDOC @@ -287,8 +293,9 @@ func (s *ArduinoCoreServerImpl) PlatformList(ctx context.Context, req *rpc.Platf // Upload FIXMEDOC func (s *ArduinoCoreServerImpl) Upload(req *rpc.UploadRequest, stream rpc.ArduinoCoreService_UploadServer) error { - outStream := feedStreamTo(func(data []byte) { stream.Send(&rpc.UploadResponse{OutStream: data}) }) - errStream := feedStreamTo(func(data []byte) { stream.Send(&rpc.UploadResponse{ErrStream: data}) }) + syncSend := NewSynchronizedSend(stream.Send) + outStream := feedStreamTo(func(data []byte) { syncSend.Send(&rpc.UploadResponse{OutStream: data}) }) + errStream := feedStreamTo(func(data []byte) { syncSend.Send(&rpc.UploadResponse{ErrStream: data}) }) err := upload.Upload(stream.Context(), req, outStream, errStream) outStream.Close() errStream.Close() @@ -300,8 +307,9 @@ func (s *ArduinoCoreServerImpl) Upload(req *rpc.UploadRequest, stream rpc.Arduin // UploadUsingProgrammer FIXMEDOC func (s *ArduinoCoreServerImpl) UploadUsingProgrammer(req *rpc.UploadUsingProgrammerRequest, stream rpc.ArduinoCoreService_UploadUsingProgrammerServer) error { - outStream := feedStreamTo(func(data []byte) { stream.Send(&rpc.UploadUsingProgrammerResponse{OutStream: data}) }) - errStream := feedStreamTo(func(data []byte) { stream.Send(&rpc.UploadUsingProgrammerResponse{ErrStream: data}) }) + syncSend := NewSynchronizedSend(stream.Send) + outStream := feedStreamTo(func(data []byte) { syncSend.Send(&rpc.UploadUsingProgrammerResponse{OutStream: data}) }) + errStream := feedStreamTo(func(data []byte) { syncSend.Send(&rpc.UploadUsingProgrammerResponse{ErrStream: data}) }) err := upload.UsingProgrammer(stream.Context(), req, outStream, errStream) outStream.Close() errStream.Close() @@ -319,15 +327,16 @@ func (s *ArduinoCoreServerImpl) SupportedUserFields(ctx context.Context, req *rp // BurnBootloader FIXMEDOC func (s *ArduinoCoreServerImpl) BurnBootloader(req *rpc.BurnBootloaderRequest, stream rpc.ArduinoCoreService_BurnBootloaderServer) error { - outStream := feedStreamTo(func(data []byte) { stream.Send(&rpc.BurnBootloaderResponse{OutStream: data}) }) - errStream := feedStreamTo(func(data []byte) { stream.Send(&rpc.BurnBootloaderResponse{ErrStream: data}) }) + syncSend := NewSynchronizedSend(stream.Send) + outStream := feedStreamTo(func(data []byte) { syncSend.Send(&rpc.BurnBootloaderResponse{OutStream: data}) }) + errStream := feedStreamTo(func(data []byte) { syncSend.Send(&rpc.BurnBootloaderResponse{ErrStream: data}) }) resp, err := upload.BurnBootloader(stream.Context(), req, outStream, errStream) outStream.Close() errStream.Close() if err != nil { return convertErrorToRPCStatus(err) } - return stream.Send(resp) + return syncSend.Send(resp) } // ListProgrammersAvailableForUpload FIXMEDOC @@ -338,49 +347,54 @@ func (s *ArduinoCoreServerImpl) ListProgrammersAvailableForUpload(ctx context.Co // LibraryDownload FIXMEDOC func (s *ArduinoCoreServerImpl) LibraryDownload(req *rpc.LibraryDownloadRequest, stream rpc.ArduinoCoreService_LibraryDownloadServer) error { + syncSend := NewSynchronizedSend(stream.Send) resp, err := lib.LibraryDownload( stream.Context(), req, - func(p *rpc.DownloadProgress) { stream.Send(&rpc.LibraryDownloadResponse{Progress: p}) }, + func(p *rpc.DownloadProgress) { syncSend.Send(&rpc.LibraryDownloadResponse{Progress: p}) }, ) if err != nil { return convertErrorToRPCStatus(err) } - return stream.Send(resp) + return syncSend.Send(resp) } // LibraryInstall FIXMEDOC func (s *ArduinoCoreServerImpl) LibraryInstall(req *rpc.LibraryInstallRequest, stream rpc.ArduinoCoreService_LibraryInstallServer) error { + syncSend := NewSynchronizedSend(stream.Send) err := lib.LibraryInstall( stream.Context(), req, - func(p *rpc.DownloadProgress) { stream.Send(&rpc.LibraryInstallResponse{Progress: p}) }, - func(p *rpc.TaskProgress) { stream.Send(&rpc.LibraryInstallResponse{TaskProgress: p}) }, + func(p *rpc.DownloadProgress) { syncSend.Send(&rpc.LibraryInstallResponse{Progress: p}) }, + func(p *rpc.TaskProgress) { syncSend.Send(&rpc.LibraryInstallResponse{TaskProgress: p}) }, ) return convertErrorToRPCStatus(err) } // LibraryUpgrade FIXMEDOC func (s *ArduinoCoreServerImpl) LibraryUpgrade(req *rpc.LibraryUpgradeRequest, stream rpc.ArduinoCoreService_LibraryUpgradeServer) error { + syncSend := NewSynchronizedSend(stream.Send) err := lib.LibraryUpgrade( stream.Context(), req, - func(p *rpc.DownloadProgress) { stream.Send(&rpc.LibraryUpgradeResponse{Progress: p}) }, - func(p *rpc.TaskProgress) { stream.Send(&rpc.LibraryUpgradeResponse{TaskProgress: p}) }, + func(p *rpc.DownloadProgress) { syncSend.Send(&rpc.LibraryUpgradeResponse{Progress: p}) }, + func(p *rpc.TaskProgress) { syncSend.Send(&rpc.LibraryUpgradeResponse{TaskProgress: p}) }, ) return convertErrorToRPCStatus(err) } // LibraryUninstall FIXMEDOC func (s *ArduinoCoreServerImpl) LibraryUninstall(req *rpc.LibraryUninstallRequest, stream rpc.ArduinoCoreService_LibraryUninstallServer) error { + syncSend := NewSynchronizedSend(stream.Send) err := lib.LibraryUninstall(stream.Context(), req, - func(p *rpc.TaskProgress) { stream.Send(&rpc.LibraryUninstallResponse{TaskProgress: p}) }, + func(p *rpc.TaskProgress) { syncSend.Send(&rpc.LibraryUninstallResponse{TaskProgress: p}) }, ) return convertErrorToRPCStatus(err) } // LibraryUpgradeAll FIXMEDOC func (s *ArduinoCoreServerImpl) LibraryUpgradeAll(req *rpc.LibraryUpgradeAllRequest, stream rpc.ArduinoCoreService_LibraryUpgradeAllServer) error { + syncSend := NewSynchronizedSend(stream.Send) err := lib.LibraryUpgradeAll(req, - func(p *rpc.DownloadProgress) { stream.Send(&rpc.LibraryUpgradeAllResponse{Progress: p}) }, - func(p *rpc.TaskProgress) { stream.Send(&rpc.LibraryUpgradeAllResponse{TaskProgress: p}) }, + func(p *rpc.DownloadProgress) { syncSend.Send(&rpc.LibraryUpgradeAllResponse{Progress: p}) }, + func(p *rpc.TaskProgress) { syncSend.Send(&rpc.LibraryUpgradeAllResponse{TaskProgress: p}) }, ) return convertErrorToRPCStatus(err) } @@ -411,18 +425,20 @@ func (s *ArduinoCoreServerImpl) ArchiveSketch(ctx context.Context, req *rpc.Arch // ZipLibraryInstall FIXMEDOC func (s *ArduinoCoreServerImpl) ZipLibraryInstall(req *rpc.ZipLibraryInstallRequest, stream rpc.ArduinoCoreService_ZipLibraryInstallServer) error { + syncSend := NewSynchronizedSend(stream.Send) err := lib.ZipLibraryInstall( stream.Context(), req, - func(p *rpc.TaskProgress) { stream.Send(&rpc.ZipLibraryInstallResponse{TaskProgress: p}) }, + func(p *rpc.TaskProgress) { syncSend.Send(&rpc.ZipLibraryInstallResponse{TaskProgress: p}) }, ) return convertErrorToRPCStatus(err) } // GitLibraryInstall FIXMEDOC func (s *ArduinoCoreServerImpl) GitLibraryInstall(req *rpc.GitLibraryInstallRequest, stream rpc.ArduinoCoreService_GitLibraryInstallServer) error { + syncSend := NewSynchronizedSend(stream.Send) err := lib.GitLibraryInstall( stream.Context(), req, - func(p *rpc.TaskProgress) { stream.Send(&rpc.GitLibraryInstallResponse{TaskProgress: p}) }, + func(p *rpc.TaskProgress) { syncSend.Send(&rpc.GitLibraryInstallResponse{TaskProgress: p}) }, ) return convertErrorToRPCStatus(err) } @@ -435,6 +451,8 @@ func (s *ArduinoCoreServerImpl) EnumerateMonitorPortSettings(ctx context.Context // Monitor FIXMEDOC func (s *ArduinoCoreServerImpl) Monitor(stream rpc.ArduinoCoreService_MonitorServer) error { + syncSend := NewSynchronizedSend(stream.Send) + // The configuration must be sent on the first message req, err := stream.Recv() if err != nil { @@ -447,7 +465,7 @@ func (s *ArduinoCoreServerImpl) Monitor(stream rpc.ArduinoCoreService_MonitorSer } // Send a message with Success set to true to notify the caller of the port being now active - _ = stream.Send(&rpc.MonitorResponse{Success: true}) + _ = syncSend.Send(&rpc.MonitorResponse{Success: true}) cancelCtx, cancel := context.WithCancel(stream.Context()) go func() { @@ -458,13 +476,13 @@ func (s *ArduinoCoreServerImpl) Monitor(stream rpc.ArduinoCoreService_MonitorSer return } if err != nil { - stream.Send(&rpc.MonitorResponse{Error: err.Error()}) + syncSend.Send(&rpc.MonitorResponse{Error: err.Error()}) return } if conf := msg.GetPortConfiguration(); conf != nil { for _, c := range conf.GetSettings() { if err := portProxy.Config(c.SettingId, c.Value); err != nil { - stream.Send(&rpc.MonitorResponse{Error: err.Error()}) + syncSend.Send(&rpc.MonitorResponse{Error: err.Error()}) } } } @@ -475,7 +493,7 @@ func (s *ArduinoCoreServerImpl) Monitor(stream rpc.ArduinoCoreService_MonitorSer return } if err != nil { - stream.Send(&rpc.MonitorResponse{Error: err.Error()}) + syncSend.Send(&rpc.MonitorResponse{Error: err.Error()}) return } tx = tx[n:] @@ -492,10 +510,10 @@ func (s *ArduinoCoreServerImpl) Monitor(stream rpc.ArduinoCoreService_MonitorSer break } if err != nil { - stream.Send(&rpc.MonitorResponse{Error: err.Error()}) + syncSend.Send(&rpc.MonitorResponse{Error: err.Error()}) break } - if err := stream.Send(&rpc.MonitorResponse{RxData: buff[:n]}); err != nil { + if err := syncSend.Send(&rpc.MonitorResponse{RxData: buff[:n]}); err != nil { break } }