Skip to content

Commit 8d1f070

Browse files
committed
pluggable-discovery handling in grpc Instances (WIP)
serial-discovery must be moved from commands/board to commands
1 parent e916764 commit 8d1f070

File tree

3 files changed

+117
-13
lines changed

3 files changed

+117
-13
lines changed

commands/board/list.go

+3-8
Original file line numberDiff line numberDiff line change
@@ -55,20 +55,15 @@ func BoardList(ctx context.Context, req *rpc.BoardListReq) (*rpc.BoardListResp,
5555
}
5656
}
5757

58-
serialDiscovery, err := discovery.NewFromCommandLine(serialDiscoveryTool.InstallDir.Join("serial-discovery").String())
58+
// TODO: move to 'commands' modules
59+
_, err := discovery.NewFromCommandLine(serialDiscoveryTool.InstallDir.Join("serial-discovery").String())
5960
if err != nil {
6061
formatter.PrintError(err, "Error setting up serial-discovery tool.")
6162
os.Exit(cli.ErrCoreConfig)
6263
}
6364

64-
// Find all installed discoveries
65-
discoveries := append(discovery.ExtractDiscoveriesFromPlatforms(pm), serialDiscovery)
66-
6765
resp := &rpc.BoardListResp{Ports: []*rpc.DetectedPort{}}
68-
for _, disc := range discoveries {
69-
disc.Start()
70-
defer disc.Close()
71-
66+
for _, disc := range commands.GetDiscoveries(req) {
7267
ports, err := disc.List()
7368
if err != nil {
7469
fmt.Printf("Error getting port list from discovery %s: %s\n", disc.ID, err)

commands/discoveries.go

+70
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
//
2+
// This file is part of arduino-cli.
3+
//
4+
// Copyright 2018 ARDUINO SA (http://www.arduino.cc/)
5+
//
6+
// This software is released under the GNU General Public License version 3,
7+
// which covers the main part of arduino-cli.
8+
// The terms of this license can be found at:
9+
// https://www.gnu.org/licenses/gpl-3.0.en.html
10+
//
11+
// You can be released from the requirements of the above licenses by purchasing
12+
// a commercial license. Buying such a license is mandatory if you want to modify or
13+
// otherwise use the software for commercial activities involving the Arduino
14+
// software without disclosing the source code of your own applications. To purchase
15+
// a commercial license, send an email to [email protected].
16+
//
17+
18+
package commands
19+
20+
import (
21+
"sync"
22+
23+
"github.com/arduino/arduino-cli/arduino/discovery"
24+
)
25+
26+
type sharedDiscovery struct {
27+
discovery *discovery.Discovery
28+
referenceCount int
29+
}
30+
31+
// this map contains all the running pluggable-discoveries instances
32+
var sharedDiscoveries = map[string]*sharedDiscovery{}
33+
var sharedDiscoveriesMutex sync.Mutex
34+
35+
// StartSharedDiscovery starts a discovery or returns the instance of an already
36+
// started shared discovery.
37+
func StartSharedDiscovery(disc *discovery.Discovery) (*discovery.Discovery, error) {
38+
sharedDiscoveriesMutex.Lock()
39+
defer sharedDiscoveriesMutex.Unlock()
40+
41+
instance, started := sharedDiscoveries[disc.ID]
42+
if started {
43+
instance.referenceCount++
44+
return instance.discovery, nil
45+
}
46+
sharedDiscoveries[disc.ID] = &sharedDiscovery{
47+
discovery: disc,
48+
referenceCount: 1,
49+
}
50+
err := disc.Start()
51+
return disc, err
52+
}
53+
54+
// StopSharedDiscovery will dispose an instance of a shared discovery if it is
55+
// no more needed.
56+
func StopSharedDiscovery(disc *discovery.Discovery) error {
57+
sharedDiscoveriesMutex.Lock()
58+
defer sharedDiscoveriesMutex.Unlock()
59+
60+
instance, started := sharedDiscoveries[disc.ID]
61+
if started {
62+
instance.referenceCount--
63+
64+
if instance.referenceCount == 0 {
65+
delete(sharedDiscoveries, disc.ID)
66+
return instance.discovery.Close()
67+
}
68+
}
69+
return nil
70+
}

commands/instances.go

+44-5
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ import (
2626
"time"
2727

2828
"github.com/arduino/arduino-cli/arduino/cores/packageindex"
29-
3029
"github.com/arduino/arduino-cli/arduino/cores/packagemanager"
30+
"github.com/arduino/arduino-cli/arduino/discovery"
3131
"github.com/arduino/arduino-cli/arduino/libraries"
3232
"github.com/arduino/arduino-cli/arduino/libraries/librariesmanager"
3333
"github.com/arduino/arduino-cli/configs"
@@ -46,10 +46,11 @@ var instancesCount int32 = 1
4646
// instantiate as many as needed by providing a different configuration
4747
// for each one.
4848
type CoreInstance struct {
49-
config *configs.Configuration
50-
pm *packagemanager.PackageManager
51-
lm *librariesmanager.LibrariesManager
52-
getLibOnly bool
49+
config *configs.Configuration
50+
pm *packagemanager.PackageManager
51+
lm *librariesmanager.LibrariesManager
52+
getLibOnly bool
53+
discoveries []*discovery.Discovery
5354
}
5455

5556
type InstanceContainer interface {
@@ -72,6 +73,32 @@ func GetLibraryManager(req InstanceContainer) *librariesmanager.LibrariesManager
7273
return i.lm
7374
}
7475

76+
func GetDiscoveries(req InstanceContainer) []*discovery.Discovery {
77+
i, ok := instances[req.GetInstance().GetId()]
78+
if !ok {
79+
return nil
80+
}
81+
return i.discoveries
82+
}
83+
84+
func (instance *CoreInstance) startDiscoveries(downloadCB DownloadProgressCB, taskCB TaskProgressCB) error {
85+
discoveriesToStop := instance.discoveries
86+
discoveriesToStart := discovery.ExtractDiscoveriesFromPlatforms(instance.pm)
87+
88+
instance.discoveries = []*discovery.Discovery{}
89+
for _, disc := range discoveriesToStart {
90+
sharedDisc, err := StartSharedDiscovery(disc)
91+
if err != nil {
92+
return fmt.Errorf("starting discovery: %s", err)
93+
}
94+
instance.discoveries = append(instance.discoveries, sharedDisc)
95+
}
96+
for _, disc := range discoveriesToStop {
97+
StopSharedDiscovery(disc)
98+
}
99+
return nil
100+
}
101+
75102
func Init(ctx context.Context, req *rpc.InitReq, downloadCB DownloadProgressCB, taskCB TaskProgressCB) (*rpc.InitResp, error) {
76103
inConfig := req.GetConfiguration()
77104
if inConfig == nil {
@@ -108,6 +135,10 @@ func Init(ctx context.Context, req *rpc.InitReq, downloadCB DownloadProgressCB,
108135
instancesCount++
109136
instances[handle] = instance
110137

138+
if err := instance.startDiscoveries(downloadCB, taskCB); err != nil {
139+
// TODO: handle discovery errors
140+
fmt.Println(err)
141+
}
111142
return &rpc.InitResp{
112143
Instance: &rpc.Instance{Id: handle},
113144
PlatformsIndexErrors: reqPltIndex,
@@ -120,6 +151,11 @@ func Destroy(ctx context.Context, req *rpc.DestroyReq) (*rpc.DestroyResp, error)
120151
if _, ok := instances[id]; !ok {
121152
return nil, fmt.Errorf("invalid handle")
122153
}
154+
155+
for _, disc := range GetDiscoveries(req) {
156+
StopSharedDiscovery(disc)
157+
}
158+
123159
delete(instances, id)
124160
return &rpc.DestroyResp{}, nil
125161
}
@@ -207,6 +243,9 @@ func Rescan(ctx context.Context, req *rpc.RescanReq) (*rpc.RescanResp, error) {
207243
}
208244
coreInstance.pm = pm
209245
coreInstance.lm = lm
246+
247+
coreInstance.startDiscoveries(nil, nil)
248+
210249
return &rpc.RescanResp{
211250
PlatformsIndexErrors: reqPltIndex,
212251
LibrariesIndexError: reqLibIndex,

0 commit comments

Comments
 (0)