Skip to content

Commit 625ff52

Browse files
committed
Discoveries are now closed and unregistered after failure (#1667)
* Discoveries are now closed and unregistered after failure * Add mutex to guard discoveries in DiscoveryManager
1 parent d684dec commit 625ff52

File tree

4 files changed

+53
-26
lines changed

4 files changed

+53
-26
lines changed

arduino/discovery/discovery.go

+4-13
Original file line numberDiff line numberDiff line change
@@ -374,21 +374,12 @@ func (disc *PluggableDiscovery) Stop() error {
374374
}
375375

376376
// Quit terminates the discovery. No more commands can be accepted by the discovery.
377-
func (disc *PluggableDiscovery) Quit() error {
378-
if err := disc.sendCommand("QUIT\n"); err != nil {
379-
return err
380-
}
381-
if msg, err := disc.waitMessage(time.Second * 10); err != nil {
382-
return fmt.Errorf(tr("calling %[1]s: %[2]w"), "QUIT", err)
383-
} else if msg.EventType != "quit" {
384-
return errors.Errorf(tr("communication out of sync, expected '%[1]s', received '%[2]s'"), "quit", msg.EventType)
385-
} else if msg.Error {
386-
return errors.Errorf(tr("command failed: %s"), msg.Message)
387-
} else if strings.ToUpper(msg.Message) != "OK" {
388-
return errors.Errorf(tr("communication out of sync, expected '%[1]s', received '%[2]s'"), "OK", msg.Message)
377+
func (disc *PluggableDiscovery) Quit() {
378+
_ = disc.sendCommand("QUIT\n")
379+
if _, err := disc.waitMessage(time.Second * 5); err != nil {
380+
logrus.Errorf("Quitting discovery %s: %s", disc.id, err)
389381
}
390382
disc.killProcess()
391-
return nil
392383
}
393384

394385
// List executes an enumeration of the ports and returns a list of the available

arduino/discovery/discovery_client/main.go

+1-3
Original file line numberDiff line numberDiff line change
@@ -135,9 +135,7 @@ out:
135135
}
136136

137137
for _, disc := range discoveries {
138-
if err := disc.Quit(); err != nil {
139-
log.Fatal("Error stopping discovery:", err)
140-
}
138+
disc.Quit()
141139
fmt.Println("Discovery QUITed")
142140
for disc.State() == discovery.Alive {
143141
time.Sleep(time.Millisecond)

arduino/discovery/discoverymanager/discoverymanager.go

+43-4
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,14 @@ import (
2222
"github.com/arduino/arduino-cli/arduino/discovery"
2323
"github.com/arduino/arduino-cli/i18n"
2424
"github.com/pkg/errors"
25+
"github.com/sirupsen/logrus"
2526
)
2627

2728
// DiscoveryManager is required to handle multiple pluggable-discovery that
2829
// may be shared across platforms
2930
type DiscoveryManager struct {
30-
discoveries map[string]*discovery.PluggableDiscovery
31+
discoveriesMutex sync.Mutex
32+
discoveries map[string]*discovery.PluggableDiscovery
3133
}
3234

3335
var tr = i18n.Tr
@@ -42,12 +44,16 @@ func New() *DiscoveryManager {
4244
// Clear resets the DiscoveryManager to its initial state
4345
func (dm *DiscoveryManager) Clear() {
4446
dm.QuitAll()
47+
dm.discoveriesMutex.Lock()
48+
defer dm.discoveriesMutex.Unlock()
4549
dm.discoveries = map[string]*discovery.PluggableDiscovery{}
4650
}
4751

4852
// IDs returns the list of discoveries' ids in this DiscoveryManager
4953
func (dm *DiscoveryManager) IDs() []string {
5054
ids := []string{}
55+
dm.discoveriesMutex.Lock()
56+
defer dm.discoveriesMutex.Unlock()
5157
for id := range dm.discoveries {
5258
ids = append(ids, id)
5359
}
@@ -57,19 +63,38 @@ func (dm *DiscoveryManager) IDs() []string {
5763
// Add adds a discovery to the list of managed discoveries
5864
func (dm *DiscoveryManager) Add(disc *discovery.PluggableDiscovery) error {
5965
id := disc.GetID()
66+
dm.discoveriesMutex.Lock()
67+
defer dm.discoveriesMutex.Unlock()
6068
if _, has := dm.discoveries[id]; has {
6169
return errors.Errorf(tr("pluggable discovery already added: %s"), id)
6270
}
6371
dm.discoveries[id] = disc
6472
return nil
6573
}
6674

75+
// remove quits and deletes the discovery with specified id
76+
// from the discoveries managed by this DiscoveryManager
77+
func (dm *DiscoveryManager) remove(id string) {
78+
dm.discoveriesMutex.Lock()
79+
d := dm.discoveries[id]
80+
delete(dm.discoveries, id)
81+
dm.discoveriesMutex.Unlock()
82+
d.Quit()
83+
logrus.Infof("Closed and removed discovery %s", id)
84+
}
85+
6786
// parallelize runs function f concurrently for each discovery.
6887
// Returns a list of errors returned by each call of f.
6988
func (dm *DiscoveryManager) parallelize(f func(d *discovery.PluggableDiscovery) error) []error {
7089
var wg sync.WaitGroup
7190
errChan := make(chan error)
91+
dm.discoveriesMutex.Lock()
92+
discoveries := []*discovery.PluggableDiscovery{}
7293
for _, d := range dm.discoveries {
94+
discoveries = append(discoveries, d)
95+
}
96+
dm.discoveriesMutex.Unlock()
97+
for _, d := range discoveries {
7398
wg.Add(1)
7499
go func(d *discovery.PluggableDiscovery) {
75100
defer wg.Done()
@@ -103,6 +128,7 @@ func (dm *DiscoveryManager) RunAll() []error {
103128
}
104129

105130
if err := d.Run(); err != nil {
131+
dm.remove(d.GetID())
106132
return fmt.Errorf(tr("discovery %[1]s process not started: %[2]w"), d.GetID(), err)
107133
}
108134
return nil
@@ -119,6 +145,7 @@ func (dm *DiscoveryManager) StartAll() []error {
119145
return nil
120146
}
121147
if err := d.Start(); err != nil {
148+
dm.remove(d.GetID())
122149
return fmt.Errorf(tr("starting discovery %[1]s: %[2]w"), d.GetID(), err)
123150
}
124151
return nil
@@ -139,6 +166,7 @@ func (dm *DiscoveryManager) StartSyncAll() (<-chan *discovery.Event, []error) {
139166

140167
eventCh, err := d.StartSync(5)
141168
if err != nil {
169+
dm.remove(d.GetID())
142170
return fmt.Errorf(tr("start syncing discovery %[1]s: %[2]w"), d.GetID(), err)
143171
}
144172

@@ -170,6 +198,7 @@ func (dm *DiscoveryManager) StopAll() []error {
170198
}
171199

172200
if err := d.Stop(); err != nil {
201+
dm.remove(d.GetID())
173202
return fmt.Errorf(tr("stopping discovery %[1]s: %[2]w"), d.GetID(), err)
174203
}
175204
return nil
@@ -185,9 +214,7 @@ func (dm *DiscoveryManager) QuitAll() []error {
185214
return nil
186215
}
187216

188-
if err := d.Quit(); err != nil {
189-
return fmt.Errorf(tr("quitting discovery %[1]s: %[2]w"), d.GetID(), err)
190-
}
217+
d.Quit()
191218
return nil
192219
})
193220
return errs
@@ -204,7 +231,13 @@ func (dm *DiscoveryManager) List() ([]*discovery.Port, []error) {
204231
Port *discovery.Port
205232
}
206233
msgChan := make(chan listMsg)
234+
dm.discoveriesMutex.Lock()
235+
discoveries := []*discovery.PluggableDiscovery{}
207236
for _, d := range dm.discoveries {
237+
discoveries = append(discoveries, d)
238+
}
239+
dm.discoveriesMutex.Unlock()
240+
for _, d := range discoveries {
208241
wg.Add(1)
209242
go func(d *discovery.PluggableDiscovery) {
210243
defer wg.Done()
@@ -243,7 +276,13 @@ func (dm *DiscoveryManager) List() ([]*discovery.Port, []error) {
243276
// ListCachedPorts return the current list of ports detected from all discoveries
244277
func (dm *DiscoveryManager) ListCachedPorts() []*discovery.Port {
245278
res := []*discovery.Port{}
279+
dm.discoveriesMutex.Lock()
280+
discoveries := []*discovery.PluggableDiscovery{}
246281
for _, d := range dm.discoveries {
282+
discoveries = append(discoveries, d)
283+
}
284+
dm.discoveriesMutex.Unlock()
285+
for _, d := range discoveries {
247286
if d.State() != discovery.Syncing {
248287
// Discovery is not syncing
249288
continue

commands/board/list.go

+5-6
Original file line numberDiff line numberDiff line change
@@ -297,15 +297,14 @@ func Watch(instanceID int32, interrupt <-chan bool) (<-chan *rpc.BoardListWatchR
297297
Error: boardsError,
298298
}
299299
case <-interrupt:
300-
errs := dm.StopAll()
301-
if len(errs) > 0 {
300+
for _, err := range dm.StopAll() {
301+
// Discoveries that return errors have their process
302+
// closed and are removed from the list of discoveries
303+
// in the manager
302304
outChan <- &rpc.BoardListWatchResponse{
303305
EventType: "error",
304-
Error: tr("stopping discoveries: %s", errs),
306+
Error: tr("stopping discoveries: %s", err),
305307
}
306-
// Don't close the channel if quitting all discoveries
307-
// failed, otherwise some processes might be left running.
308-
continue
309308
}
310309
return
311310
}

0 commit comments

Comments
 (0)