@@ -2,13 +2,16 @@ package database
2
2
3
3
import (
4
4
"context"
5
+ "errors"
5
6
"net/url"
6
7
"os"
7
8
"path"
8
9
"sort"
9
10
"strings"
11
+ "time"
10
12
11
13
"github.com/lithammer/fuzzysearch/fuzzy"
14
+ "golang.org/x/sync/errgroup"
12
15
13
16
"cdr.dev/slog"
14
17
@@ -52,6 +55,7 @@ func (db *NoDB) GetExtensionAssetPath(ctx context.Context, asset *Asset, baseURL
52
55
func (db * NoDB ) GetExtensions (ctx context.Context , filter Filter , flags Flag , baseURL url.URL ) ([]* Extension , int , error ) {
53
56
vscodeExts := []* noDBExtension {}
54
57
58
+ start := time .Now ()
55
59
err := db .Storage .WalkExtensions (ctx , func (manifest * storage.VSIXManifest , versions []string ) error {
56
60
vscodeExt := convertManifestToExtension (manifest )
57
61
if matched , distances := getMatches (vscodeExt , filter ); matched {
@@ -66,9 +70,22 @@ func (db *NoDB) GetExtensions(ctx context.Context, filter Filter, flags Flag, ba
66
70
}
67
71
68
72
total := len (vscodeExts )
73
+ db .Logger .Debug (ctx , "walk extensions" , slog .F ("took" , time .Since (start )), slog .F ("count" , total ))
74
+
75
+ start = time .Now ()
69
76
sortExtensions (vscodeExts , filter )
77
+ db .Logger .Debug (ctx , "sort extensions" , slog .F ("took" , time .Since (start )))
78
+
79
+ start = time .Now ()
70
80
vscodeExts = paginateExtensions (vscodeExts , filter )
71
- db .handleFlags (ctx , vscodeExts , flags , baseURL )
81
+ db .Logger .Debug (ctx , "paginate extensions" , slog .F ("took" , time .Since (start )))
82
+
83
+ start = time .Now ()
84
+ err = db .handleFlags (ctx , vscodeExts , flags , baseURL )
85
+ if err != nil {
86
+ return nil , 0 , err
87
+ }
88
+ db .Logger .Debug (ctx , "handle flags" , slog .F ("took" , time .Since (start )))
72
89
73
90
convertedExts := []* Extension {}
74
91
for _ , ext := range vscodeExts {
@@ -250,7 +267,8 @@ func paginateExtensions(exts []*noDBExtension, filter Filter) []*noDBExtension {
250
267
return exts [start :end ]
251
268
}
252
269
253
- func (db * NoDB ) handleFlags (ctx context.Context , exts []* noDBExtension , flags Flag , baseURL url.URL ) {
270
+ func (db * NoDB ) handleFlags (ctx context.Context , exts []* noDBExtension , flags Flag , baseURL url.URL ) error {
271
+ var eg errgroup.Group
254
272
for _ , ext := range exts {
255
273
// Files, properties, and asset URIs are part of versions so if they are set
256
274
// assume we also want to include versions.
@@ -259,7 +277,17 @@ func (db *NoDB) handleFlags(ctx context.Context, exts []*noDBExtension, flags Fl
259
277
flags & IncludeVersionProperties != 0 ||
260
278
flags & IncludeLatestVersionOnly != 0 ||
261
279
flags & IncludeAssetURI != 0 {
262
- ext .Versions = db .getVersions (ctx , ext , flags , baseURL )
280
+ // Depending on the storage mechanism fetching a manifest can be very
281
+ // slow so run the requests in parallel.
282
+ ext := ext
283
+ eg .Go (func () error {
284
+ versions , err := db .getVersions (ctx , ext , flags , baseURL )
285
+ if err != nil {
286
+ return err
287
+ }
288
+ ext .Versions = versions
289
+ return nil
290
+ })
263
291
}
264
292
265
293
// TODO: This does not seem to be included in any interfaces so no idea
@@ -279,9 +307,10 @@ func (db *NoDB) handleFlags(ctx context.Context, exts []*noDBExtension, flags Fl
279
307
// if flags&IncludeStatistics != 0 {}
280
308
// if flags&Unpublished != 0 {}
281
309
}
310
+ return eg .Wait ()
282
311
}
283
312
284
- func (db * NoDB ) getVersions (ctx context.Context , ext * noDBExtension , flags Flag , baseURL url.URL ) []ExtVersion {
313
+ func (db * NoDB ) getVersions (ctx context.Context , ext * noDBExtension , flags Flag , baseURL url.URL ) ( []ExtVersion , error ) {
285
314
ctx = slog .With (ctx ,
286
315
slog .F ("publisher" , ext .Publisher .PublisherName ),
287
316
slog .F ("extension" , ext .Name ))
@@ -295,8 +324,10 @@ func (db *NoDB) getVersions(ctx context.Context, ext *noDBExtension, flags Flag,
295
324
for _ , versionStr := range versionStrs {
296
325
ctx := slog .With (ctx , slog .F ("version" , versionStr ))
297
326
manifest , err := db .Storage .Manifest (ctx , ext .Publisher .PublisherName , ext .Name , versionStr )
298
- if err != nil {
299
- db .Logger .Error (ctx , "Unable to parse version manifest" , slog .Error (err ))
327
+ if err != nil && errors .Is (err , context .Canceled ) {
328
+ return nil , err
329
+ } else if err != nil {
330
+ db .Logger .Error (ctx , "Unable to read version manifest" , slog .Error (err ))
300
331
continue
301
332
}
302
333
@@ -354,7 +385,7 @@ func (db *NoDB) getVersions(ctx context.Context, ext *noDBExtension, flags Flag,
354
385
355
386
versions = append (versions , version )
356
387
}
357
- return versions
388
+ return versions , nil
358
389
}
359
390
360
391
// noDBExtension adds some properties for internally filtering.
0 commit comments