Created
February 7, 2022 17:10
-
-
Save miketromba/458c2e1895eea9f411d69b0d8d16b603 to your computer and use it in GitHub Desktop.
FifoOperationQueueCache.js
This file contains hidden or 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
// @ts-nocheck | |
function createDeferredPromise(){ | |
let res, rej | |
const promise = new Promise((resolve, reject) => { [res, rej] = [resolve, reject] }) | |
promise.resolve = res | |
promise.reject = rej | |
return promise | |
} | |
class FifoOperationQueue { | |
constructor({ onEmpty }){ | |
this.onEmpty = onEmpty || function(){} | |
this.idGen = 0 | |
this.queue = [] | |
this.promises = {} | |
this.state = 'idle' | |
} | |
generateId(){ | |
return this.idGen++ | |
} | |
push(operation, input){ | |
// Init queue array | |
const itemId = this.generateId() | |
this.queue.push({ | |
operation, | |
input, | |
id: itemId | |
}) | |
// Create promise | |
const dPromise = this.promises[itemId] = createDeferredPromise() | |
// Run the queue (don't await) | |
this.runQueue() | |
// Return dPromise so client can await on it's completion if it needs | |
return dPromise | |
} | |
async runQueue(){ | |
// Already running, skip. | |
if(this.state == 'running'){ return } | |
// Set status to running | |
this.state = 'running' | |
// Execute operations (FIFO) until queue is empty | |
while(this.queue.length){ | |
// Pull the first item from the queue | |
const item = this.queue.shift() | |
const promise = this.promises[item.id] | |
delete this.promises[item.id] | |
try { | |
promise.resolve( | |
await item.operation(item.input) | |
) | |
} | |
catch(e){ promise.reject(e) } | |
} | |
// Emit on empty | |
this.onEmpty() | |
// Set status for this queue to idle | |
this.state = 'idle' | |
} | |
} | |
export default class FifoOperationQueueCache { | |
constructor(){ | |
this.queues = {} | |
} | |
push(queueId, operation, input){ | |
// Init queue array | |
if(!this.queues[queueId]){ | |
const self = this | |
this.queues[queueId] = new FifoOperationQueue({ | |
onEmpty(){ delete self.queues[queueId] } | |
}) | |
} | |
// Returns a promise | |
return this.queues[queueId].push(operation, input) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment