Skip to content

Commit 21b585d

Browse files
fix
Signed-off-by: Roman Nikitenko <rnikiten@redhat.com>
1 parent c55fc95 commit 21b585d

1 file changed

Lines changed: 52 additions & 18 deletions

File tree

code/src/vs/server/node/che/defaultExtensionsInstaller.ts

Lines changed: 52 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import { URI } from '../../../base/common/uri.js';
1616
import { IFileService } from '../../../platform/files/common/files.js';
1717
import { INativeServerExtensionManagementService } from '../../../platform/extensionManagement/node/extensionManagementService.js';
1818
import { 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';
2020
import { ILogService } from '../../../platform/log/common/log.js';
2121
import { IUserDataProfilesService } from '../../../platform/userDataProfile/common/userDataProfile.js';
2222
import { 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

Comments
 (0)