@@ -343,7 +343,7 @@ export class ExtensionGalleryService implements IExtensionGalleryService {
343343
344344 declare readonly _serviceBrand : undefined ;
345345
346- private extensionsGalleryUrl : string | undefined ;
346+ private extensionsGalleryUrl : string [ ] | undefined ;
347347 private extensionsControlUrl : string | undefined ;
348348
349349 private readonly commonHeadersPromise : Promise < { [ key : string ] : string ; } > ;
@@ -363,8 +363,13 @@ export class ExtensionGalleryService implements IExtensionGalleryService {
363363 this . commonHeadersPromise = resolveMarketplaceHeaders ( productService . version , this . environmentService , this . fileService , storageService ) ;
364364 }
365365
366- private api ( path = '' ) : string {
367- return `${ this . extensionsGalleryUrl } ${ path } ` ;
366+ private api ( path = '' ) : string [ ] {
367+ if ( ! ! this . extensionsGalleryUrl ) {
368+ return this . extensionsGalleryUrl ?. map (
369+ ( galleryUrl ) => `${ galleryUrl } ${ path } `
370+ )
371+ }
372+ return [ ] ;
368373 }
369374
370375 isEnabled ( ) : boolean {
@@ -543,43 +548,53 @@ export class ExtensionGalleryService implements IExtensionGalleryService {
543548 'Content-Length' : String ( data . length )
544549 } ;
545550
546- const context = await this . requestService . request ( {
547- type : 'POST' ,
548- url : this . api ( '/extensionquery' ) ,
549- data,
550- headers
551- } , token ) ;
551+ const galleryExtensions : IRawGalleryExtension [ ] = [ ] ;
552+ const seenExtensions : Set < String > = new Set ( ) ;
552553
553- if ( context . res . statusCode && context . res . statusCode >= 400 && context . res . statusCode < 500 ) {
554- return { galleryExtensions : [ ] , total : 0 } ;
555- }
554+ for ( const url of this . api ( '/extensionquery' ) ) {
555+ const context = await this . requestService . request ( {
556+ type : 'POST' ,
557+ url : url ,
558+ data,
559+ headers
560+ } , token ) ;
556561
557- const result = await asJson < IRawGalleryQueryResult > ( context ) ;
558- if ( result ) {
559- const r = result . results [ 0 ] ;
560- const galleryExtensions = r . extensions ;
561- const resultCount = r . resultMetadata && r . resultMetadata . filter ( m => m . metadataType === 'ResultCount' ) [ 0 ] ;
562- const total = resultCount && resultCount . metadataItems . filter ( i => i . name === 'TotalCount' ) [ 0 ] . count || 0 ;
562+ if ( context . res . statusCode && context . res . statusCode >= 400 && context . res . statusCode < 500 ) {
563+ return { galleryExtensions : [ ] , total : 0 } ;
564+ }
563565
564- return { galleryExtensions, total } ;
566+ const result = await asJson < IRawGalleryQueryResult > ( context ) ;
567+ if ( result ) {
568+ const r = result . results [ 0 ] ;
569+ for ( const extension of r . extensions ) {
570+ if ( ! seenExtensions . has ( extension . extensionId ) ) {
571+ galleryExtensions . push ( extension ) ;
572+ seenExtensions . add ( extension . extensionId ) ;
573+ }
574+ }
575+ }
565576 }
566- return { galleryExtensions : [ ] , total : 0 } ;
577+ return { galleryExtensions, total : galleryExtensions . length } ;
567578 }
568579
569580 async reportStatistic ( publisher : string , name : string , version : string , type : StatisticType ) : Promise < void > {
581+ // TODO: investigate further - currently we just send stats everywhere
582+ // this is only used in one place - uninstall tracking - but
570583 if ( ! this . isEnabled ( ) ) {
571584 return undefined ;
572585 }
573586
574587 const commonHeaders = await this . commonHeadersPromise ;
575588 const headers = { ...commonHeaders , Accept : '*/*;api-version=4.0-preview.1' } ;
576- try {
577- await this . requestService . request ( {
578- type : 'POST' ,
579- url : this . api ( `/publishers/${ publisher } /extensions/${ name } /${ version } /stats?statType=${ type } ` ) ,
580- headers
581- } , CancellationToken . None ) ;
582- } catch ( error ) { /* Ignore */ }
589+ for ( const url of this . api ( `/publishers/${ publisher } /extensions/${ name } /${ version } /stats?statType=${ type } ` ) ) {
590+ try {
591+ await this . requestService . request ( {
592+ type : 'POST' ,
593+ url : url ,
594+ headers
595+ } , CancellationToken . None ) ;
596+ } catch ( error ) { /* Ignore */ }
597+ }
583598 }
584599
585600 async download ( extension : IGalleryExtension , location : URI , operation : InstallOperation ) : Promise < void > {
0 commit comments