@@ -5,8 +5,12 @@ import (
55 "errors"
66 "fmt"
77 "log/slog"
8+ "net/http"
89 "strings"
910 "sync"
11+ "time"
12+
13+ "golang.org/x/sync/errgroup"
1014)
1115
1216var ErrOperationAlreadyInProgress = errors .New ("an operation is already in progress" )
@@ -56,15 +60,42 @@ func (m *Manager) ListUpgradablePackages(ctx context.Context, matcher func(Upgra
5660 }
5761 defer m .lock .Unlock ()
5862
59- arduinoPkgs , err := m .arduinoPlatformUpdateService .ListUpgradablePackages (ctx , matcher )
60- if err != nil {
61- return nil , err
63+ // Make sure to be connected to the internet, before checking for updates.
64+ // This is needed because the checks below work also when offline (using cached data).
65+ if ! isConnected () {
66+ return nil , errors .New ("no internet connectivity" )
6267 }
6368
64- debPkgs , err := m .debUpdateService .ListUpgradablePackages (ctx , matcher )
65- if err != nil {
69+ // Get the list of upgradable packages from two sources (deb and platform) in parallel.
70+ g , ctx := errgroup .WithContext (ctx )
71+ var (
72+ debPkgs []UpgradablePackage
73+ arduinoPkgs []UpgradablePackage
74+ )
75+
76+ g .Go (func () error {
77+ pkgs , err := m .debUpdateService .ListUpgradablePackages (ctx , matcher )
78+ if err != nil {
79+ return err
80+ }
81+ debPkgs = pkgs
82+ return nil
83+ })
84+
85+ g .Go (func () error {
86+ pkgs , err := m .arduinoPlatformUpdateService .ListUpgradablePackages (ctx , matcher )
87+ if err != nil {
88+ return err
89+ }
90+ arduinoPkgs = pkgs
91+ return nil
92+ })
93+
94+ // Wait for all the checks to complete (or any to fail).
95+ if err := g .Wait (); err != nil {
6696 return nil , err
6797 }
98+
6899 return append (arduinoPkgs , debPkgs ... ), nil
69100}
70101
@@ -161,3 +192,19 @@ func (b *Manager) broadcast(event Event) {
161192 }
162193 }
163194}
195+
196+ func isConnected () bool {
197+ client := http.Client {
198+ Timeout : 3 * time .Second ,
199+ }
200+
201+ // Just check that the connection can be estabilished.
202+ // The HEAD method will not get the results and we are ignoring the HTTP status code.
203+ resp , err := client .Head ("https://downloads.arduino.cc/" )
204+ if err != nil {
205+ return false
206+ }
207+ defer resp .Body .Close ()
208+
209+ return true
210+ }
0 commit comments