Skip to content

Commit 8acba78

Browse files
committed
Wait for schemas to be loaded
1 parent 75d2c64 commit 8acba78

File tree

5 files changed

+39
-48
lines changed

5 files changed

+39
-48
lines changed

src/datastore/LMDB.ts

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import { stats } from './lmdb/Stats';
1212
import { encryptionStrategy } from './lmdb/Utils';
1313

1414
export class LMDBStoreFactory implements DataStoreFactory {
15-
private isClosed: boolean = false;
1615
private readonly log = LoggerFactory.getLogger('LMDB.Global');
1716
@Telemetry({ scope: 'LMDB.Global' }) private readonly telemetry!: ScopedTelemetry;
1817

@@ -87,18 +86,14 @@ export class LMDBStoreFactory implements DataStoreFactory {
8786
}
8887

8988
async close(): Promise<void> {
90-
if (this.isClosed) {
91-
return;
92-
}
89+
clearInterval(this.metricsInterval);
90+
clearTimeout(this.timeout);
9391

9492
// Clear the stores map but don't close individual stores
9593
// LMDB will close them when we close the environment
96-
clearInterval(this.metricsInterval);
97-
clearTimeout(this.timeout);
9894
this.stores.clear();
9995
await this.env.flushed;
10096
await this.env.close();
101-
this.isClosed = true;
10297
}
10398

10499
private cleanupOldVersions(): void {

src/server/CfnServer.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@ import { ServerComponents } from './ServerComponents';
6161

6262
const log = LoggerFactory.getLogger('CfnServer');
6363
export class CfnServer {
64-
private isClosed: boolean = false;
6564
private readonly components: ServerComponents;
6665

6766
constructor(
@@ -290,10 +289,6 @@ export class CfnServer {
290289
}
291290

292291
async close(): Promise<void> {
293-
if (this.isClosed) {
294-
return;
295-
}
296292
await closeSafely(this.providers, this.external, this.core);
297-
this.isClosed = true;
298293
}
299294
}

tst/utils/TestExtension.ts

Lines changed: 27 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ import { MultiDataStoreFactoryProvider } from '../../src/datastore/DataStore';
5353
import { FeatureFlagProvider } from '../../src/featureFlag/FeatureFlagProvider';
5454
import { LspCapabilities } from '../../src/protocol/LspCapabilities';
5555
import { LspConnection } from '../../src/protocol/LspConnection';
56+
import { SamStoreKey } from '../../src/schema/SamSchemas';
5657
import { SchemaRetriever } from '../../src/schema/SchemaRetriever';
5758
import { SchemaStore } from '../../src/schema/SchemaStore';
5859
import { CfnExternal } from '../../src/server/CfnExternal';
@@ -61,6 +62,7 @@ import { CfnLspProviders } from '../../src/server/CfnLspProviders';
6162
import { CfnServer } from '../../src/server/CfnServer';
6263
import { AwsMetadata, ExtendedInitializeParams } from '../../src/server/InitParams';
6364
import { RelationshipSchemaService } from '../../src/services/RelationshipSchemaService';
65+
import { DefaultSettings } from '../../src/settings/Settings';
6466
import { LoggerFactory } from '../../src/telemetry/LoggerFactory';
6567
import { Closeable } from '../../src/utils/Closeable';
6668
import { ExtensionName } from '../../src/utils/ExtensionConfig';
@@ -108,8 +110,7 @@ export class TestExtension implements Closeable {
108110
providers!: CfnLspProviders;
109111
server!: CfnServer;
110112

111-
private lspClientReady = false;
112-
private lspServerReady = false;
113+
private isReady = false;
113114

114115
constructor() {
115116
this.serverConnection = new LspConnection(
@@ -154,16 +155,9 @@ export class TestExtension implements Closeable {
154155
this.server = new CfnServer(lsp, this.core, this.external, this.providers);
155156
return LspCapabilities;
156157
},
157-
onInitialized: (params) => {
158-
this.server.initialized(params);
159-
this.lspServerReady = true;
160-
},
161-
onShutdown: () => {
162-
return this.server.close();
163-
},
164-
onExit: () => {
165-
return this.server.close();
166-
},
158+
onInitialized: (params) => this.server.initialized(params),
159+
onShutdown: () => this.server.close(),
160+
onExit: () => this.server.close(),
167161
},
168162
);
169163

@@ -185,40 +179,39 @@ export class TestExtension implements Closeable {
185179
}
186180

187181
async ready() {
188-
if (!this.lspClientReady) {
182+
if (!this.isReady) {
189183
await this.clientConnection.sendRequest(InitializeRequest.type, this.initializeParams);
190184
await this.clientConnection.sendNotification(InitializedNotification.type, {});
191-
this.lspClientReady = true;
192-
}
193185

194-
await WaitFor.waitFor(() => {
195-
if (!this.lspServerReady) {
196-
throw new Error('Server is not ready yet');
197-
}
198-
}, 5000);
186+
await WaitFor.waitFor(() => {
187+
const store = this.external.schemaStore;
188+
const pbSchemas = store?.publicSchemas?.get(DefaultSettings.profile.region);
189+
const samSchemas = store?.samSchemas?.get(SamStoreKey);
190+
191+
if (pbSchemas === undefined || samSchemas === undefined) {
192+
throw new Error('Schemas not loaded yet');
193+
}
194+
}, 2_500);
199195

200-
await flushAllPromises();
196+
await flushAllPromises();
197+
this.isReady = true;
198+
}
201199
}
202200

203201
async send(method: string, params: any) {
204202
await this.ready();
205-
const value = await this.clientConnection.sendRequest(method, params);
206-
await wait(100);
207-
return value;
203+
return await this.clientConnection.sendRequest(method, params);
208204
}
209205

210206
async notify(method: string, params: any) {
211207
await this.ready();
212-
const value = await this.clientConnection.sendNotification(method, params);
213-
await wait(100);
214-
return value;
208+
return await this.clientConnection.sendNotification(method, params);
215209
}
216210

217211
async close() {
218212
await this.clientConnection.sendRequest(ShutdownRequest.type);
219213
await this.clientConnection.sendNotification(ExitNotification.type);
220214
this.clientConnection.dispose();
221-
await flushAllPromises();
222215
}
223216

224217
// ====================================================================
@@ -227,18 +220,22 @@ export class TestExtension implements Closeable {
227220

228221
async openDocument(params: DidOpenTextDocumentParams) {
229222
await this.notify(DidOpenTextDocumentNotification.method, params);
223+
await wait(10);
230224
}
231225

232226
async changeDocument(params: DidChangeTextDocumentParams) {
233227
await this.notify(DidChangeTextDocumentNotification.method, params);
228+
await wait(10);
234229
}
235230

236231
async closeDocument(params: DidCloseTextDocumentParams) {
237232
await this.notify(DidCloseTextDocumentNotification.method, params);
233+
await wait(10);
238234
}
239235

240-
saveDocument(params: DidSaveTextDocumentParams) {
241-
return this.notify(DidSaveTextDocumentNotification.method, params);
236+
async saveDocument(params: DidSaveTextDocumentParams) {
237+
await this.notify(DidSaveTextDocumentNotification.method, params);
238+
await wait(10);
242239
}
243240

244241
completion(params: CompletionParams) {

tst/utils/Utils.ts

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
export function flushAllPromises() {
2-
return new Promise((resolve) => {
3-
setTimeout(resolve, 0);
4-
});
1+
import { setImmediate } from 'node:timers/promises';
2+
3+
export async function flushAllPromises() {
4+
await setImmediate();
55
}
66

77
export class WaitFor {
@@ -33,7 +33,11 @@ export class WaitFor {
3333
throw lastError!;
3434
}
3535

36-
static async waitFor(code: () => void | Promise<void>, timeoutMs: number = 100): Promise<void> {
37-
await new WaitFor(timeoutMs).wait(code);
36+
static async waitFor(
37+
code: () => void | Promise<void>,
38+
timeoutMs: number = 100,
39+
intervalMs: number = 10,
40+
): Promise<void> {
41+
await new WaitFor(timeoutMs, intervalMs).wait(code);
3842
}
3943
}

0 commit comments

Comments
 (0)