Only abort pending image requests
In case images are requested of a slow source, aborting image requests that are already in progress will cause the server to take forever for new source image requests because it's still processing the aborted image requests. Thus, aborting ongoing image request might cause more harm than good, since the server will basically become "unresponsive" for new images requests of this source. By only aborting pending requests, that have not been sent to the server yet, new image requests will only be handled once the active requests are done, preventing the server from getting spammed with image requests that potentially are just getting aborted immediately again (e.g. due to scrolling quickly in the source browse page), but still will be handled by the server, blocking new requests
This commit is contained in:
@@ -44,7 +44,11 @@ export class Queue {
|
||||
this.pendingKeyToPromiseMap.clear();
|
||||
}
|
||||
|
||||
enqueue<T>(key: Key, fn: () => PromiseLike<T> | T, priority: QueuePriority = Priority.NORMAL): Promise<T> {
|
||||
enqueue<T>(
|
||||
key: Key,
|
||||
fn: () => PromiseLike<T> | T,
|
||||
priority: QueuePriority = Priority.NORMAL,
|
||||
): { key: string; promise: Promise<T> } {
|
||||
this.counter = (this.counter + 1) % Infinity;
|
||||
const actualKey = `${key}_${this.counter}`;
|
||||
|
||||
@@ -56,7 +60,11 @@ export class Queue {
|
||||
|
||||
this.queue(() => this.process());
|
||||
|
||||
return processPromise.promise;
|
||||
return { key: actualKey, promise: processPromise.promise };
|
||||
}
|
||||
|
||||
isProcessing(key: string): boolean {
|
||||
return !this.pendingKeyToFnMap.has(key);
|
||||
}
|
||||
|
||||
private async process(): Promise<void> {
|
||||
|
||||
@@ -812,7 +812,7 @@ export class RequestManager {
|
||||
imgRequest.reject(reason);
|
||||
};
|
||||
|
||||
const response = this.imageQueue.enqueue(
|
||||
const { key, promise: response } = this.imageQueue.enqueue(
|
||||
url,
|
||||
async () => {
|
||||
// throws error in case request was already aborted
|
||||
@@ -829,7 +829,21 @@ export class RequestManager {
|
||||
priority,
|
||||
);
|
||||
|
||||
return { response, abortRequest, cleanup: () => {} };
|
||||
return {
|
||||
response,
|
||||
abortRequest: (reason?: any) => {
|
||||
if (this.imageQueue.isProcessing(key)) {
|
||||
// prevent aborting image requests that are already in progress
|
||||
// e.g. for source image requests, ongoing requests are already handled by the server and aborting them
|
||||
// will just cause new source image requests to be sent to the server, which then will cause the server
|
||||
// to become really slow for image requests to the same source
|
||||
return;
|
||||
}
|
||||
|
||||
abortRequest(reason);
|
||||
},
|
||||
cleanup: () => {},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -848,7 +862,7 @@ export class RequestManager {
|
||||
private fetchImageViaFetchApi(url: string, priority?: QueuePriority): ImageRequest {
|
||||
let objectUrl: string = '';
|
||||
const { abortRequest, signal } = this.createAbortController();
|
||||
const response = this.imageQueue.enqueue(
|
||||
const { key, promise: response } = this.imageQueue.enqueue(
|
||||
url,
|
||||
() =>
|
||||
this.restClient
|
||||
@@ -869,7 +883,21 @@ export class RequestManager {
|
||||
priority,
|
||||
);
|
||||
|
||||
return { response, abortRequest, cleanup: () => URL.revokeObjectURL(objectUrl) };
|
||||
return {
|
||||
response,
|
||||
abortRequest: (reason?: any) => {
|
||||
if (this.imageQueue.isProcessing(key)) {
|
||||
// prevent aborting image requests that are already in progress
|
||||
// e.g. for source image requests, ongoing requests are already handled by the server and aborting them
|
||||
// will just cause new source image requests to be sent to the server, which then will cause the server
|
||||
// to become really slow for image requests to the same source
|
||||
return;
|
||||
}
|
||||
|
||||
abortRequest(reason);
|
||||
},
|
||||
cleanup: () => URL.revokeObjectURL(objectUrl),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user