Skip to content

Commit 30ddcff

Browse files
committed
Abort content downloads on exit
1 parent 239d4c7 commit 30ddcff

File tree

4 files changed

+51
-34
lines changed

4 files changed

+51
-34
lines changed

.changeset/chilled-swans-wash.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@bluecadet/launchpad-content": patch
3+
---
4+
5+
Abort content downloads on exit

packages/content/lib/launchpad-content.js

Lines changed: 34 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import FileUtils from './utils/file-utils.js';
1818
import MdToHtmlTransform from './content-transforms/md-to-html-transform.js';
1919
import ContentTransform from './content-transforms/content-transform.js';
2020

21-
import { LogManager, Logger } from '@bluecadet/launchpad-utils';
21+
import { LogManager, Logger, onExit } from '@bluecadet/launchpad-utils';
2222
import ContentResult from './content-sources/content-result.js';
2323
import SanityToPlainTransform from './content-transforms/sanity-to-plain.js';
2424
import SanityToHtmlTransform from './content-transforms/sanity-to-html.js';
@@ -59,19 +59,19 @@ export class LaunchpadContent {
5959
return Promise.reject(error);
6060
}
6161
}
62-
62+
6363
/** @type {import('./content-options.js').ResolvedContentOptions} */
6464
_config;
6565

6666
/** @type {Logger} */
6767
_logger;
68-
68+
6969
/** @type {Array<ContentSource>} */
7070
_sources = [];
71-
71+
7272
/** @type {MediaDownloader} */
7373
_mediaDownloader;
74-
74+
7575
/** @type {Map<string, ContentTransform>} */
7676
_contentTransforms = new Map();
7777

@@ -91,7 +91,7 @@ export class LaunchpadContent {
9191
this._contentTransforms.set('sanityToHtml', new SanityToHtmlTransform());
9292
this._contentTransforms.set('sanityToMd', new SanityToMarkdownTransform());
9393
this._contentTransforms.set('sanityToMarkdown', new SanityToMarkdownTransform());
94-
94+
9595
if (this._config.credentialsPath) {
9696
try {
9797
Credentials.init(this._config.credentialsPath, this._logger);
@@ -101,11 +101,12 @@ export class LaunchpadContent {
101101
}
102102
}
103103
}
104-
104+
105105
this.sources = this._createSources(this._config.sources);
106-
// onExit(() => {
107-
// // TODO: Abort media downloader and wait for remaining downloads to finish
108-
// });
106+
107+
onExit(async () => {
108+
this._mediaDownloader.abort();
109+
});
109110
}
110111

111112
/**
@@ -118,17 +119,17 @@ export class LaunchpadContent {
118119
this._logger.warn(chalk.yellow('No sources found to download'));
119120
return Promise.resolve();
120121
}
121-
122+
122123
try {
123124
this._logger.info(`Downloading ${chalk.cyan(sources.length)} sources`);
124-
125+
125126
if (this._config.backupAndRestore) {
126127
this._logger.info(`Backing up ${chalk.cyan(sources.length)} sources`);
127128
await this.backup(sources);
128129
}
129-
130+
130131
let sourcesComplete = 0;
131-
132+
132133
for (const source of sources) {
133134
const progress = (sourcesComplete + 1) + '/' + sources.length;
134135
this._logger.info(`Downloading source ${chalk.cyan(progress)}: ${chalk.yellow(source)}`);
@@ -140,7 +141,7 @@ export class LaunchpadContent {
140141

141142
sourcesComplete++;
142143
}
143-
144+
144145
this._logger.info(
145146
chalk.green(`Finished downloading ${sources.length} sources`)
146147
);
@@ -151,7 +152,7 @@ export class LaunchpadContent {
151152
await this.restore(sources);
152153
}
153154
}
154-
155+
155156
try {
156157
this._logger.debug('Cleaning up temp and backup files');
157158
await this.clear(sources, {
@@ -162,10 +163,10 @@ export class LaunchpadContent {
162163
} catch (err) {
163164
this._logger.error('Could not clean up temp and backup files', err);
164165
}
165-
166+
166167
return Promise.resolve();
167168
}
168-
169+
169170
/**
170171
* Alias for start(source)
171172
* @param {Array<ContentSource>} sources
@@ -174,7 +175,7 @@ export class LaunchpadContent {
174175
async download(sources = []) {
175176
return this.start(sources);
176177
}
177-
178+
178179
/**
179180
* Clears all cached content except for files that match config.keep.
180181
* @param {Array<ContentSource>} sources The sources you want to clear. If left undefined, this will clear all known sources. If no sources are passed, the entire downloads/temp/backup dirs are removed.
@@ -207,7 +208,7 @@ export class LaunchpadContent {
207208
await this._clearDir(this.getDownloadPath(source), { removeIfEmpty });
208209
}
209210
}
210-
211+
211212
if (removeIfEmpty && temp) {
212213
await FileUtils.removeDirIfEmpty(this.getTempPath());
213214
}
@@ -217,10 +218,10 @@ export class LaunchpadContent {
217218
if (removeIfEmpty && downloads) {
218219
await FileUtils.removeDirIfEmpty(this.getDownloadPath());
219220
}
220-
221+
221222
return Promise.resolve();
222223
}
223-
224+
224225
/**
225226
* Backs up all downloads of source to a separate backup dir.
226227
* @param {Array<ContentSource>} sources
@@ -240,7 +241,7 @@ export class LaunchpadContent {
240241
}
241242
}
242243
}
243-
244+
244245
/**
245246
* Restores all downloads of source from its backup dir if it exists.
246247
* @param {Array<ContentSource>} sources
@@ -265,7 +266,7 @@ export class LaunchpadContent {
265266
}
266267
}
267268
}
268-
269+
269270
/**
270271
* @param {ContentSource} [source]
271272
* @returns {string}
@@ -277,7 +278,7 @@ export class LaunchpadContent {
277278
return path.resolve(this._config.downloadPath);
278279
}
279280
}
280-
281+
281282
/**
282283
* @param {ContentSource} [source]
283284
* @returns {string}
@@ -292,7 +293,7 @@ export class LaunchpadContent {
292293
return detokenizedPath;
293294
}
294295
}
295-
296+
296297
/**
297298
* @param {ContentSource} [source]
298299
* @returns {string}
@@ -307,7 +308,7 @@ export class LaunchpadContent {
307308
return detokenizedPath;
308309
}
309310
}
310-
311+
311312
/**
312313
* @param {import('./content-options.js').ContentOptions['sources']} sourceConfigs
313314
* @returns {Array<ContentSource>}
@@ -317,14 +318,14 @@ export class LaunchpadContent {
317318
this._logger.warn('No content sources found in config.');
318319
return [];
319320
}
320-
321+
321322
const sources = [];
322323

323324
/**
324325
* @type {(import('./content-options.js').AllSourceOptions)[]}
325326
*/
326327
let sourceConfigArray = [];
327-
328+
328329
if (!Array.isArray(sourceConfigs)) {
329330
// Backwards compatibility for key/value-based
330331
// configs where the key is the source ID
@@ -380,7 +381,7 @@ export class LaunchpadContent {
380381
this._logger.error('Could not create content source:', err);
381382
}
382383
}
383-
384+
384385
return sources;
385386
}
386387

@@ -447,12 +448,12 @@ export class LaunchpadContent {
447448
this._logger.error(`Unsupported content transform: '${transformId}'`);
448449
continue;
449450
}
450-
451+
451452
const transformIdStr = chalk.yellow(transformId);
452453
const pathStr = chalk.yellow(path);
453454
const localPathStr = chalk.yellow(resultData.localPath);
454455
const transformer = this._contentTransforms.get(transformId);
455-
456+
456457
try {
457458
if (!transformer) {
458459
throw new Error(`Could not find content transform '${transformId}'`);
@@ -473,7 +474,7 @@ export class LaunchpadContent {
473474

474475
return Promise.resolve(result);
475476
}
476-
477+
477478
/**
478479
* @param {string} dirPath
479480
*/

packages/content/lib/utils/media-downloader.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ export class MediaDownloader {
2929
this.logger = logger || console;
3030
}
3131

32+
#abortController = new AbortController();
33+
3234
/**
3335
* Downloads a set of URLs into a destination folder.
3436
*
@@ -203,6 +205,13 @@ export class MediaDownloader {
203205
}
204206
}
205207

208+
/**
209+
* Abort all downloads in progress
210+
*/
211+
abort() {
212+
this.#abortController.abort();
213+
}
214+
206215
/**
207216
* @param {MediaDownload} task
208217
* @param {string} tempDir Directory path for temporary files
@@ -229,6 +238,7 @@ export class MediaDownloader {
229238
// Get just the file header to check for modified date and file size
230239
const response = await got.head(task.url, {
231240
headers: this._getRequestHeaders(destPath),
241+
signal: this.#abortController.signal,
232242
timeout: {
233243
response: options.maxTimeout
234244
}
@@ -260,6 +270,7 @@ export class MediaDownloader {
260270
if (!isCached) {
261271
await pipeline(
262272
got.stream(task.url, {
273+
signal: this.#abortController.signal,
263274
timeout: {
264275
response: options.maxTimeout
265276
}

packages/content/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
"cli-progress": "^3.9.1",
4545
"contentful": "^9.0.0",
4646
"filenamify": "^5.1.1",
47-
"fs-extra": "^10.0.0",
47+
"fs-extra": "^11.2.0",
4848
"get-urls": "^12.1.0",
4949
"got": "^12.3.0",
5050
"jsonpath": "^1.1.1",

0 commit comments

Comments
 (0)