Skip to content

Commit 84d52e8

Browse files
committed
feat(storage): add maxConcurrentUploads concurrency limit
1 parent a19ca62 commit 84d52e8

3 files changed

Lines changed: 19 additions & 3 deletions

File tree

packages/core/src/storages/config.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ export class ConfigHandler {
1818
path: '/files',
1919
validation: {},
2020
maxMetadataSize: '4MB',
21-
logger: logger
21+
logger: logger,
22+
maxConcurrentUploads: 0
2223
};
2324

2425
private _config = this.set(ConfigHandler.defaults);

packages/core/src/storages/storage.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,11 @@ export interface BaseStorageOptions<T extends File> {
108108
* @defaultValue 'none'
109109
*/
110110
logLevel?: LogLevel;
111+
112+
/**
113+
* Limits the number of concurrent upload requests
114+
*/
115+
maxConcurrentUploads?: number;
111116
}
112117

113118
const LOCK_TIMEOUT = 300; // seconds
@@ -288,15 +293,23 @@ export abstract class BaseStorage<TFile extends File> {
288293

289294
/**
290295
* Prevent upload from being accessed by multiple requests
296+
* Limits the number of concurrent upload requests
291297
*/
292298
async lock(key: string): Promise<string> {
299+
const max = this.config.maxConcurrentUploads;
300+
if (max && locker.keys().length >= max) {
301+
return fail(ERRORS.TOO_MANY_UPLOADS);
302+
}
293303
try {
294304
return locker.lock(key);
295305
} catch {
296306
return fail(ERRORS.FILE_LOCKED);
297307
}
298308
}
299309

310+
/**
311+
* Unlocks a previously locked upload
312+
*/
300313
async unlock(key: string): Promise<void> {
301314
locker.unlock(key);
302315
}

packages/core/src/utils/errors.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ export enum ERRORS {
2424
CHECKSUM_MISMATCH = 'ChecksumMismatch',
2525
UNSUPPORTED_CHECKSUM_ALGORITHM = 'UnsupportedChecksumAlgorithm',
2626
REQUEST_ABORTED = 'RequestAborted',
27-
FILE_LOCKED = 'FileLocked'
27+
FILE_LOCKED = 'FileLocked',
28+
TOO_MANY_UPLOADS = 'TooManyUploads'
2829
}
2930

3031
export type ErrorResponses<T extends string = string> = {
@@ -56,7 +57,8 @@ class E_ {
5657
UnprocessableEntity: [422, 'Validation failed'],
5758
UnsupportedMediaType: [415, 'Unsupported media type'],
5859
RequestAborted: [499, 'Request aborted'],
59-
FileLocked: [423, 'File locked']
60+
FileLocked: [423, 'File locked'],
61+
TooManyUploads: [503, 'Too many active uploads, please try again later']
6062
};
6163

6264
static _buildErrorBody = (target: typeof E_, _: string): void => {

0 commit comments

Comments
 (0)