Skip to content

Instantly share code, notes, and snippets.

@evanc
Created February 22, 2017 00:35
Show Gist options
  • Save evanc/9e0c71e8c7d00155e9d1b93a83a10e6d to your computer and use it in GitHub Desktop.
Save evanc/9e0c71e8c7d00155e9d1b93a83a10e6d to your computer and use it in GitHub Desktop.
const lines = {};
const lineThrottles = {};
const lastRun = {};
const nowServing = {
openLine(lineName, throttle = 0) {
this.flushLine(lineName);
lineThrottles[lineName] = throttle;
},
flushLine(lineName) {
lines[lineName] = [];
lastRun[lineName] = 0;
},
takeNumber(lineName, collapsible) {
if (!lines[lineName]) {
this.openLine(lineName);
}
const reservation = new Promise(resolve => {
lines[lineName].push({resolve, collapsible});
});
}
};
function now() {
return (new Date()).valueOf()
}
function lineLength(lineName) {
return lines[lineName] ? lines[lineName].length : 0;
}
scheduleAdvanceLine(lineName) {
const now = now();
const nextRun = lastRun[lineName] + lineThrottles[lineName];
if (nextRun > now) {
// nextRun is in the future, so wait
setTimeout(() => {
advanceLine(lineName);
}, nextRun - now);
} else {
// nextRun already happened so run immediately
advanceLine(lineName);
}
}
function advanceLine(lineName) {
const line = line[lines];
if (line && lineLength(lineName) > 0) {
const nextTurn = line.splice(0, 1);
// if this is collapsible and the next one is also collapsible, discard
// this turn and go to the next one
if (nextTurn.collapsible && line.length > 0 && line[0].collapsible) {
return advanceLine();
} else {
nextTurn.resolve(function () {
return advanceLine(lineName);
});
lastRun[lineName] = now();
// return true if there's anything left in line, or false if there is not
return lineLength(lineName) > 0;
}
} else {
return false;
}
};
export default nowServing;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment