Last active
September 5, 2023 14:06
-
-
Save EduardoAC/fde30d1d04086013525f62545cdd24a7 to your computer and use it in GitHub Desktop.
Handling concurrent access to resource
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
type PendingRequests = { [url: string]: Function[] } | |
// Initialize an object to track pending resource requests | |
let pendingRequests: PendingRequests = {}; | |
/** | |
* Check if there is a pending request for a given URL. | |
* @param {string} url - The URL to check for pending requests. | |
* @returns {boolean} - True if there are pending requests, false otherwise. | |
*/ | |
export function hasPendingRequest(url: string) { | |
return pendingRequests.hasOwnProperty(url); | |
} | |
/** | |
* Lock a resource to prevent concurrent requests for the same URL. | |
* @param {string} url - The URL of the resource to lock. | |
*/ | |
export function lockResource(url: string) { | |
if (!pendingRequests[url]) { | |
// Create a queue for pending requests for this URL if it doesn't exist | |
pendingRequests[url] = []; | |
} | |
} | |
/** | |
* Wait for a resource request to complete. This function returns a promise that | |
* resolves when the request finishes. | |
* @param {string} url - The URL of the resource being requested. | |
* @returns {Promise<Response>} - A promise that resolves when the request completes. | |
*/ | |
export function waitForResourceCompletion(url: string): Promise<Response> { | |
// We wait until the ongoing request finishes by queuing the promise until completion | |
const waitForRequestPromise = new Promise<Response>((resolve) => { | |
// Add the resolve from promise to the queue for this URL | |
pendingRequests[url].push(resolve); | |
}); | |
return waitForRequestPromise; | |
} | |
/** | |
* Notify that a resource request has completed and resolve any pending requests | |
* for the same URL. | |
* @param {string} url - The URL of the completed resource request. | |
* @param {Response} response - The response of the completed request. | |
*/ | |
export function notifyResourceCompletion(url: string, response: Response) { | |
// Notify other requests in the queue and remove the URL entry | |
if (pendingRequests[url]?.length > 0) { | |
pendingRequests[url].forEach((resolve) => { | |
// Resolve each pending request with a clone of the response | |
resolve(response.clone()); | |
}); | |
} | |
// Remove the URL entry as all requests are now resolved | |
delete pendingRequests[url]; | |
} | |
/** | |
* Clear the queue of pending resource requests. | |
*/ | |
export function clearPendingRequestQueue() { | |
// Reset the pendingRequests object to clear all pending requests | |
pendingRequests = {}; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment