Skip to content

Commit

Permalink
Use WebWorkers and add a cache
Browse files Browse the repository at this point in the history
  • Loading branch information
JasonGross committed Nov 19, 2023
1 parent 0f1088d commit e417a02
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 27 deletions.
2 changes: 1 addition & 1 deletion fiat-html/fiat-crypto.html
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
<button type="button" id="cancelButton" disabled>Cancel</button>
<span id="status" class="status-span hidden"></span>
<a id="permalink" class="permalink-span hidden" href="#">Pseudopermalink</a>
<button type="button" id="clearCacheButton">Clear Cache</button>
</div>
</form>
<div id="error" class="error hidden"></div>
Expand All @@ -64,7 +65,6 @@
<button class="copy-button" data-target="stderr">Copy</button>
</div>
</div>
<script src="fiat_crypto.js"></script>
<script src="main.js"></script>
<script src="copy-button.js"></script>
</body>
Expand Down
5 changes: 5 additions & 0 deletions fiat-html/fiat_crypto_worker.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
self.importScripts("fiat_crypto.js");
self.onmessage = function(e) {
const result = synthesize(e.data);
postMessage(result);
};
103 changes: 77 additions & 26 deletions fiat-html/main.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// Written with help from https://chat.openai.com/share/74d5901c-9005-4560-8307-582ff54e403e
const SYNTHESIS_CACHE_VERSION = 1;
document.addEventListener('DOMContentLoaded', function() {
const errorDiv = document.getElementById('error');
const outputDiv = document.getElementById('output');
Expand All @@ -10,6 +11,7 @@ document.addEventListener('DOMContentLoaded', function() {
const inputArgs = document.getElementById('inputArgs');
const synthesizeButton = document.getElementById('synthesizeButton');
const cancelButton = document.getElementById('cancelButton');
const clearCacheButton = document.getElementById('clearCacheButton');
const permalink = document.getElementById('permalink');
const statusSpan = document.getElementById('status');
const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
Expand Down Expand Up @@ -135,7 +137,7 @@ document.addEventListener('DOMContentLoaded', function() {
}
}

function handleSynthesisResult(result) {
function handleSynthesisResultData(result) {
const success = result[0];
const exceptionText = result[1];
const stdout = result[2];
Expand Down Expand Up @@ -168,40 +170,82 @@ document.addEventListener('DOMContentLoaded', function() {
updateStatus(""); // Clear status
}

function handleSynthesisResult(result, cached) {
const cachedString = cached ? ` (cached on ${result.timestamp})` : '';
if (result.success) {
clearOutput();
updateStatus(`Synthesis${cachedString} completed in ${result.time} seconds`);
handleSynthesisResultData(result.result);
} else {
handleException(result.result);
updateStatus(`Synthesis${cachedString} failed in ${result.time} seconds`);
}
}

let synthesisWorker;

function setupSynthesisWorker() {
synthesisWorker = new Worker("fiat_crypto_worker.js");

synthesisWorker.onmessage = function(e) {
console.log(`Early synthesis result: ${e.data}`);
};

synthesisWorker.onerror = function(err) {
handleException(err);
};
}

function cancelSynthesisWorker() {
if (synthesisWorker) {
synthesisWorker.terminate();
console.log("Synthesis worker terminated.");
}
setupSynthesisWorker(); // Re-setup the worker for future use
}

var curSynthesisPromise;
function handleSynthesis(args) {
const startTime = performance.now();
const cacheKey = 'synthesize_' + JSON.stringify(args);
const cached = localStorage.getItem(cacheKey);
console.log({'synthesize args': args});
updateStatus("Synthesizing...");
updatePermalink(args);
const synthesisPromise = new Promise((resolve, reject) => {
try {
resolve(synthesize(args))
} catch (error) {
reject(error);

if (cached) {
const cachedData = JSON.parse(cached);
if (cachedData.version === SYNTHESIS_CACHE_VERSION) {
handleSynthesisResult(cachedData, true);
return;
} else {
console.log(`cache miss: version ${cachedData.version}, expected ${SYNTHESIS_CACHE_VERSION}`)
}
});
curSynthesisPromise = synthesisPromise;
synthesisPromise
.then((value) => {
if (curSynthesisPromise === synthesisPromise) {
const endTime = performance.now();
clearOutput();
updateStatus(`Synthesis completed in ${(endTime - startTime) / 1000} seconds`);
handleSynthesisResult(value);
} else {
console.log(`Synthesis of ${args} completed after being canceled: ${value}`);
}
})
.catch((err) => {
if (curSynthesisPromise === synthesisPromise) {
handleException(err);
} else {
console.log(`Synthesis of ${args} errored after being canceled: ${err}`);
}

const recieveMessage = function (success) {
return function(e) {
const endTime = performance.now();
const timeTaken = (endTime - startTime) / 1000;
const now = new Date();
const resultData = {
result: e.data,
time: timeTaken,
success: success,
timestamp: now.toISOString(),
version: SYNTHESIS_CACHE_VERSION
};
try {
localStorage.setItem(cacheKey, JSON.stringify(resultData));
} catch (e) {
console.error(`Failed: localStorage.setItem(${JSON.stringify(cacheKey)}, ${JSON.stringify(JSON.stringify(resultData))})`);
}
});
handleSynthesisResult(resultData, false);
};
};

synthesisWorker.postMessage(args);
synthesisWorker.onmessage = recieveMessage(true);
synthesisWorker.onerror = recieveMessage(false);
}

function parseAndRun(argv) {
Expand All @@ -214,6 +258,8 @@ document.addEventListener('DOMContentLoaded', function() {
}
}

setupSynthesisWorker();

const queryParams = new URLSearchParams(window.location.search);
const argv = queryParams.get('argv');
const interactive = queryParams.get('interactive');
Expand Down Expand Up @@ -267,5 +313,10 @@ document.addEventListener('DOMContentLoaded', function() {
synthesizeButton.disabled = false;
cancelButton.disabled = true;
updateStatus("");
cancelSynthesisWorker();
});

clearCacheButton.addEventListener('click', function() {
localStorage.clear();
});
});

0 comments on commit e417a02

Please sign in to comment.