Skip to content

Commit 4fb1bbd

Browse files
chore: when closing ExportsManager should not accept any more requests
1 parent 9998d8e commit 4fb1bbd

File tree

2 files changed

+38
-1
lines changed

2 files changed

+38
-1
lines changed

src/common/exportsManager.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ type ExportsManagerEvents = {
6464

6565
export class ExportsManager extends EventEmitter<ExportsManagerEvents> {
6666
private wasInitialized: boolean = false;
67+
private isShuttingDown: boolean = false;
6768
private storedExports: Record<StoredExport["exportName"], StoredExport> = {};
6869
private exportsCleanupInProgress: boolean = false;
6970
private exportsCleanupInterval?: NodeJS.Timeout;
@@ -77,6 +78,7 @@ export class ExportsManager extends EventEmitter<ExportsManagerEvents> {
7778
}
7879

7980
public get availableExports(): AvailableExport[] {
81+
this.assertIsNotShuttingDown();
8082
return Object.values(this.storedExports)
8183
.filter((storedExport) => {
8284
return (
@@ -103,6 +105,11 @@ export class ExportsManager extends EventEmitter<ExportsManagerEvents> {
103105
}
104106

105107
public async close(): Promise<void> {
108+
if (this.isShuttingDown) {
109+
return;
110+
}
111+
112+
this.isShuttingDown = true;
106113
try {
107114
clearInterval(this.exportsCleanupInterval);
108115
await fs.rm(this.exportsDirectoryPath, { force: true, recursive: true });
@@ -117,6 +124,7 @@ export class ExportsManager extends EventEmitter<ExportsManagerEvents> {
117124

118125
public async readExport(exportName: string): Promise<string> {
119126
try {
127+
this.assertIsNotShuttingDown();
120128
exportName = decodeURIComponent(exportName);
121129
const exportHandle = this.storedExports[exportName];
122130
if (!exportHandle) {
@@ -157,6 +165,7 @@ export class ExportsManager extends EventEmitter<ExportsManagerEvents> {
157165
jsonExportFormat: JSONExportFormat;
158166
}): AvailableExport {
159167
try {
168+
this.assertIsNotShuttingDown();
160169
const exportNameWithExtension = validateExportName(ensureExtension(exportName, "json"));
161170
if (this.storedExports[exportNameWithExtension]) {
162171
throw new Error("Export with same name is either already available or being generated.");
@@ -270,7 +279,7 @@ export class ExportsManager extends EventEmitter<ExportsManagerEvents> {
270279
}
271280

272281
private async cleanupExpiredExports(): Promise<void> {
273-
if (this.exportsCleanupInProgress) {
282+
if (this.exportsCleanupInProgress || this.isShuttingDown) {
274283
return;
275284
}
276285

@@ -318,6 +327,12 @@ export class ExportsManager extends EventEmitter<ExportsManagerEvents> {
318327
}
319328
}
320329

330+
private assertIsNotShuttingDown(): void {
331+
if (this.isShuttingDown) {
332+
throw new Error("ExportsManager is shutting down.");
333+
}
334+
}
335+
321336
static init(sessionId: string, config: ExportsManagerConfig, logger: LoggerBase): ExportsManager {
322337
const exportsDirectoryPath = path.join(config.exportsPath, sessionId);
323338
const exportsManager = new ExportsManager(exportsDirectoryPath, config, logger);

tests/unit/common/exportsManager.test.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,11 @@ describe("ExportsManager unit test", () => {
130130
});
131131

132132
describe("#availableExport", () => {
133+
it("should throw if the manager is shutting down", () => {
134+
void manager.close();
135+
expect(() => manager.availableExports).toThrow("ExportsManager is shutting down.");
136+
});
137+
133138
it("should list only the exports that are in ready state", async () => {
134139
// This export will finish in at-least 1 second
135140
const { exportName: exportName1 } = getExportNameAndPath(session.sessionId);
@@ -156,6 +161,11 @@ describe("ExportsManager unit test", () => {
156161
});
157162

158163
describe("#readExport", () => {
164+
it("should throw if the manager is shutting down", async () => {
165+
void manager.close();
166+
await expect(() => manager.readExport("name")).rejects.toThrow("ExportsManager is shutting down.");
167+
});
168+
159169
it("should throw when export name has no extension", async () => {
160170
await expect(() => manager.readExport("name")).rejects.toThrow();
161171
});
@@ -208,6 +218,18 @@ describe("ExportsManager unit test", () => {
208218
({ exportName, exportPath, exportURI } = getExportNameAndPath(session.sessionId));
209219
});
210220

221+
it("should throw if the manager is shutting down", () => {
222+
const { cursor } = createDummyFindCursor([]);
223+
void manager.close();
224+
expect(() =>
225+
manager.createJSONExport({
226+
input: cursor,
227+
exportName,
228+
jsonExportFormat: "relaxed",
229+
})
230+
).toThrow();
231+
});
232+
211233
describe("when cursor is empty", () => {
212234
it("should create an empty export", async () => {
213235
const { cursor, cursorCloseNotification } = createDummyFindCursor([]);

0 commit comments

Comments
 (0)