Last active
May 30, 2022 06:25
-
-
Save victorporof/f8bab8eaf12231366056d6c00bd1ff55 to your computer and use it in GitHub Desktop.
Async Stack Tagging API (Recurring)
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
/* --- Userland --- */ | |
function makeUpdate(i) { | |
return function someUpdate() { | |
console.trace(`completeUpdate: update ${i}`); | |
}; | |
} | |
function businessLogic() { | |
scheduler.scheduleTask("foo", [makeUpdate(1), makeUpdate(2), makeUpdate(3)]); | |
scheduler.scheduleTask("bar", [makeUpdate(4), makeUpdate(5)]); | |
} | |
businessLogic(); | |
scheduler.scheduleWorkLoop(); |
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
/* --- Framework --- */ | |
function makeTask(id, name, updates) { | |
return { | |
performNextUpdate() { | |
console.info(`Performing next update within task '${name}'.`); | |
const f = updates.shift(); | |
console.startAsyncTask(id); | |
f(); | |
console.finishAsyncTask(id); | |
if (updates.length) { | |
console.info(`Task '${name}' has ${updates.length} updates remaining.`); | |
return false; | |
} | |
console.info(`Task '${name}' finished, no updates remaining here.`); | |
console.cancelAsyncTask(id); | |
return true; | |
}, | |
}; | |
} | |
function makeScheduler() { | |
const tasks = []; | |
function workLoop(deadline) { | |
console.info(`Started new work loop.`); | |
while (deadline.ticksRemaining() > 0 && tasks.length) { | |
const task = tasks[0]; | |
const finished = task.performNextUpdate(); | |
if (finished) { | |
tasks.shift(); | |
} | |
} | |
if (tasks.length) { | |
console.warn("Exceeded deadline but not finished, yielding."); | |
fakeRequestIdleCallback(workLoop); | |
return; | |
} | |
console.info("Work loop finished, no tasks remaining here."); | |
} | |
return { | |
scheduleTask(name, updates) { | |
const id = console.scheduleAsyncTask(name, true); | |
tasks.push(makeTask(id, name, updates)); | |
console.info(`Scheduld task '${name}' with ${updates.length} updates.`); | |
}, | |
scheduleWorkLoop() { | |
fakeRequestIdleCallback(workLoop); | |
}, | |
}; | |
} | |
const scheduler = makeScheduler(); |
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
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8" /> | |
<title>Async Tasks API</title> | |
</head> | |
<body> | |
<script src="runtime.js"></script> | |
<script src="framework.js"></script> | |
<script src="async-stack-tagging-recurring.js"></script> | |
</body> | |
</html> |
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
/* --- Runtime --- */ | |
// Something akin to requestIdleCallback, but deterministic. | |
const BUDGET = 2; | |
function fakeRequestIdleCallback(cb) { | |
function makeDeadline() { | |
let ticks = BUDGET; | |
return { | |
ticksRemaining() { | |
return ticks--; | |
}, | |
}; | |
} | |
setTimeout(cb, 1000, makeDeadline()); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment