@@ -16,7 +16,7 @@ import { URI } from '../../../base/common/uri.js';
1616import { IFileService } from '../../../platform/files/common/files.js' ;
1717import { INativeServerExtensionManagementService } from '../../../platform/extensionManagement/node/extensionManagementService.js' ;
1818import { IExtensionGalleryService } from '../../../platform/extensionManagement/common/extensionManagement.js' ;
19- import { IExtensionGalleryManifestService } from '../../../platform/extensionManagement/common/extensionGalleryManifest.js' ;
19+ import { IExtensionGalleryManifestService , ExtensionGalleryManifestStatus } from '../../../platform/extensionManagement/common/extensionGalleryManifest.js' ;
2020import { ILogService } from '../../../platform/log/common/log.js' ;
2121import { IUserDataProfilesService } from '../../../platform/userDataProfile/common/userDataProfile.js' ;
2222import { IRemoteExtensionsScannerService } from '../../../platform/remote/common/remoteExtensionsScanner.js' ;
@@ -47,25 +47,53 @@ export class DefaultExtensionsInstaller extends Disposable {
4747 }
4848
4949 this . logService . info ( 'DefaultExtensionsInstaller: Waiting for gallery service to be enabled' ) ;
50+ this . logService . info ( `DefaultExtensionsInstaller: Current gallery manifest status: ${ this . extensionGalleryManifestService . extensionGalleryManifestStatus } ` ) ;
5051
51- // Wait for the manifest to be available (uses barrier internally)
52- // This is the proper way to wait - the barrier opens when manifest is set from client
53- try {
54- const manifest = await Promise . race ( [
55- this . extensionGalleryManifestService . getExtensionGalleryManifest ( ) ,
56- new Promise < null > ( ( resolve ) => setTimeout ( ( ) => resolve ( null ) , 10000 ) ) // 10 second timeout
57- ] ) ;
52+ // Use event-based waiting - wait for the status to become Available
53+ // The gallery manifest is set by the client via IPC, so we need to wait for client connection
54+ return new Promise < boolean > ( ( resolve ) => {
55+ const maxWaitTime = 60000 ; // 60 seconds - client needs time to connect and set manifest
56+ const startTime = Date . now ( ) ;
5857
59- if ( manifest && this . extensionGalleryService . isEnabled ( ) ) {
60- this . logService . info ( 'DefaultExtensionsInstaller: Gallery service is now enabled' ) ;
61- return true ;
58+ const timeout = setTimeout ( ( ) => {
59+ disposable . dispose ( ) ;
60+ const elapsed = Date . now ( ) - startTime ;
61+ this . logService . warn ( `DefaultExtensionsInstaller: Gallery service is not enabled after waiting ${ elapsed } ms` ) ;
62+ this . logService . info ( `DefaultExtensionsInstaller: Current status: ${ this . extensionGalleryManifestService . extensionGalleryManifestStatus } , isEnabled: ${ this . extensionGalleryService . isEnabled ( ) } ` ) ;
63+ resolve ( false ) ;
64+ } , maxWaitTime ) ;
65+
66+ const disposable = this . extensionGalleryManifestService . onDidChangeExtensionGalleryManifestStatus ( ( status ) => {
67+ this . logService . info ( `DefaultExtensionsInstaller: Gallery manifest status changed to: ${ status } ` ) ;
68+ if ( status === ExtensionGalleryManifestStatus . Available && this . extensionGalleryService . isEnabled ( ) ) {
69+ clearTimeout ( timeout ) ;
70+ disposable . dispose ( ) ;
71+ this . logService . info ( 'DefaultExtensionsInstaller: Gallery service is now enabled' ) ;
72+ resolve ( true ) ;
73+ }
74+ } ) ;
75+
76+ // Check immediately in case it's already available
77+ if ( this . extensionGalleryManifestService . extensionGalleryManifestStatus === ExtensionGalleryManifestStatus . Available && this . extensionGalleryService . isEnabled ( ) ) {
78+ clearTimeout ( timeout ) ;
79+ disposable . dispose ( ) ;
80+ this . logService . info ( 'DefaultExtensionsInstaller: Gallery service is already enabled (checked after listener setup)' ) ;
81+ resolve ( true ) ;
6282 }
63- } catch ( error ) {
64- this . logService . warn ( 'DefaultExtensionsInstaller: Error waiting for gallery manifest' , error ) ;
65- }
66-
67- this . logService . warn ( 'DefaultExtensionsInstaller: Gallery service is not enabled after waiting' ) ;
68- return false ;
83+
84+ // Also try the barrier approach as a fallback (waits for client to set manifest via IPC)
85+ this . extensionGalleryManifestService . getExtensionGalleryManifest ( ) . then ( manifest => {
86+ if ( manifest && this . extensionGalleryService . isEnabled ( ) ) {
87+ clearTimeout ( timeout ) ;
88+ disposable . dispose ( ) ;
89+ this . logService . info ( 'DefaultExtensionsInstaller: Gallery service is enabled (via manifest barrier)' ) ;
90+ resolve ( true ) ;
91+ }
92+ } ) . catch ( ( error ) => {
93+ this . logService . debug ( 'DefaultExtensionsInstaller: Error waiting for manifest barrier' , error ) ;
94+ // Ignore errors, rely on event or timeout
95+ } ) ;
96+ } ) ;
6997 }
7098
7199 private async initialize ( ) : Promise < void > {
@@ -80,10 +108,16 @@ export class DefaultExtensionsInstaller extends Disposable {
80108 return ;
81109 }
82110
111+ // Add a small delay to allow client to connect and set gallery manifest
112+ // The gallery manifest is set by the client via IPC, so we need to wait for client connection
113+ this . logService . info ( 'DefaultExtensionsInstaller: Waiting briefly for client connection' ) ;
114+ await new Promise ( resolve => setTimeout ( resolve , 2000 ) ) ; // 2 second delay
115+
83116 // Wait for gallery service to be enabled so dependencies can be installed from the gallery
117+ // This is critical - without gallery service, dependencies won't be installed
84118 const galleryEnabled = await this . waitForGalleryService ( ) ;
85119 if ( ! galleryEnabled ) {
86- this . logService . warn ( 'DefaultExtensionsInstaller: Proceeding without gallery service - dependencies may not be installed' ) ;
120+ this . logService . warn ( 'DefaultExtensionsInstaller: Gallery service is not enabled - dependencies may not be installed' ) ;
87121 }
88122 const defaultExtensionsEnv = typeof process !== 'undefined' && process . env ? process . env [ 'DEFAULT_EXTENSIONS_NEW' ] : undefined ;
89123 if ( ! defaultExtensionsEnv ) {
0 commit comments