@@ -2,13 +2,16 @@ package database
22
33import (
44 "context"
5+ "errors"
56 "net/url"
67 "os"
78 "path"
89 "sort"
910 "strings"
11+ "time"
1012
1113 "github.com/lithammer/fuzzysearch/fuzzy"
14+ "golang.org/x/sync/errgroup"
1215
1316 "cdr.dev/slog"
1417
@@ -52,6 +55,7 @@ func (db *NoDB) GetExtensionAssetPath(ctx context.Context, asset *Asset, baseURL
5255func (db * NoDB ) GetExtensions (ctx context.Context , filter Filter , flags Flag , baseURL url.URL ) ([]* Extension , int , error ) {
5356 vscodeExts := []* noDBExtension {}
5457
58+ start := time .Now ()
5559 err := db .Storage .WalkExtensions (ctx , func (manifest * storage.VSIXManifest , versions []string ) error {
5660 vscodeExt := convertManifestToExtension (manifest )
5761 if matched , distances := getMatches (vscodeExt , filter ); matched {
@@ -66,9 +70,22 @@ func (db *NoDB) GetExtensions(ctx context.Context, filter Filter, flags Flag, ba
6670 }
6771
6872 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 ()
6976 sortExtensions (vscodeExts , filter )
77+ db .Logger .Debug (ctx , "sort extensions" , slog .F ("took" , time .Since (start )))
78+
79+ start = time .Now ()
7080 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 )))
7289
7390 convertedExts := []* Extension {}
7491 for _ , ext := range vscodeExts {
@@ -250,7 +267,8 @@ func paginateExtensions(exts []*noDBExtension, filter Filter) []*noDBExtension {
250267 return exts [start :end ]
251268}
252269
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
254272 for _ , ext := range exts {
255273 // Files, properties, and asset URIs are part of versions so if they are set
256274 // assume we also want to include versions.
@@ -259,7 +277,17 @@ func (db *NoDB) handleFlags(ctx context.Context, exts []*noDBExtension, flags Fl
259277 flags & IncludeVersionProperties != 0 ||
260278 flags & IncludeLatestVersionOnly != 0 ||
261279 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+ })
263291 }
264292
265293 // 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
279307 // if flags&IncludeStatistics != 0 {}
280308 // if flags&Unpublished != 0 {}
281309 }
310+ return eg .Wait ()
282311}
283312
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 ) {
285314 ctx = slog .With (ctx ,
286315 slog .F ("publisher" , ext .Publisher .PublisherName ),
287316 slog .F ("extension" , ext .Name ))
@@ -295,8 +324,10 @@ func (db *NoDB) getVersions(ctx context.Context, ext *noDBExtension, flags Flag,
295324 for _ , versionStr := range versionStrs {
296325 ctx := slog .With (ctx , slog .F ("version" , versionStr ))
297326 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 ))
300331 continue
301332 }
302333
@@ -354,7 +385,7 @@ func (db *NoDB) getVersions(ctx context.Context, ext *noDBExtension, flags Flag,
354385
355386 versions = append (versions , version )
356387 }
357- return versions
388+ return versions , nil
358389}
359390
360391// noDBExtension adds some properties for internally filtering.
0 commit comments