204 lines
5.9 KiB
HTML
204 lines
5.9 KiB
HTML
|
<!DOCTYPE html>
|
||
|
<head>
|
||
|
<title>Forum Network</title>
|
||
|
<link type="text/css" rel="stylesheet" href="/index.css" />
|
||
|
</head>
|
||
|
<body>
|
||
|
<div id="basic"></div>
|
||
|
</body>
|
||
|
<script type="module">
|
||
|
import { Box } from "/classes/box.js";
|
||
|
import { Scene } from "/classes/scene.js";
|
||
|
|
||
|
const rootElement = document.getElementById("basic");
|
||
|
const rootBox = new Box("rootBox", rootElement).flex();
|
||
|
|
||
|
function randomDelay(min, max) {
|
||
|
const delayMs = min + Math.random() * max;
|
||
|
return delayMs;
|
||
|
}
|
||
|
|
||
|
function delay(min, max = min) {
|
||
|
const delayMs = min + Math.random() * (max - min);
|
||
|
return new Promise((resolve) => {
|
||
|
setTimeout(resolve, delayMs);
|
||
|
});
|
||
|
}
|
||
|
|
||
|
if (true) {
|
||
|
const scene = new Scene("Scene 1", rootBox);
|
||
|
const webClientStatus = scene.addDisplayValue("WebClient Status");
|
||
|
const node1Status = scene.addDisplayValue("Node 1 Status");
|
||
|
const blockchainStatus = scene.addDisplayValue("Blockchain Status");
|
||
|
|
||
|
const webClient = scene.addActor("web client");
|
||
|
const node1 = scene.addActor("node 1");
|
||
|
const blockchain = scene.addActor("blockchain");
|
||
|
const requestForumPage = scene.addAction("requestForumPage");
|
||
|
const readBlockchainData = scene.addAction("readBlockchainData");
|
||
|
const blockchainData = scene.addAction("blockchainData");
|
||
|
const forumPage = scene.addAction("forumPage");
|
||
|
|
||
|
webClientStatus.set("Initialized");
|
||
|
node1Status.set("Idle");
|
||
|
blockchainStatus.set("Idle");
|
||
|
|
||
|
node1.on(requestForumPage, (src, detail) => {
|
||
|
node1Status.set("Processing request");
|
||
|
node1.on(blockchainData, (_src, data) => {
|
||
|
node1Status.set("Processing response");
|
||
|
setTimeout(() => {
|
||
|
node1.send(src, forumPage, data);
|
||
|
node1Status.set("Idle");
|
||
|
}, randomDelay(500, 1000));
|
||
|
});
|
||
|
setTimeout(() => {
|
||
|
node1.send(blockchain, readBlockchainData, detail);
|
||
|
}, randomDelay(500, 1500));
|
||
|
});
|
||
|
|
||
|
blockchain.on(readBlockchainData, (src, _detail) => {
|
||
|
blockchainStatus.set("Processing request");
|
||
|
setTimeout(() => {
|
||
|
blockchain.send(src, blockchainData, {});
|
||
|
blockchainStatus.set("Idle");
|
||
|
}, randomDelay(500, 1500));
|
||
|
});
|
||
|
|
||
|
webClient.on(forumPage, (_src, _detail) => {
|
||
|
webClientStatus.set("Received forum page");
|
||
|
});
|
||
|
|
||
|
setInterval(() => {
|
||
|
webClient.send(node1, requestForumPage);
|
||
|
webClientStatus.set("Requested forum page");
|
||
|
}, randomDelay(6000, 12000));
|
||
|
}
|
||
|
|
||
|
(async function run() {
|
||
|
const scene = new Scene("Scene 2", rootBox);
|
||
|
|
||
|
const webClient = scene.addActor("webClient");
|
||
|
|
||
|
const nodes = [];
|
||
|
const memories = [];
|
||
|
const storages = [];
|
||
|
|
||
|
function addNode() {
|
||
|
const idx = nodes.length;
|
||
|
const node = scene.addActor(`node${idx}`);
|
||
|
const memory = scene.addActor(`memory${idx}`);
|
||
|
const storage = scene.addActor(`storage${idx}`);
|
||
|
node.memory = memory;
|
||
|
node.storage = storage;
|
||
|
nodes.push(node);
|
||
|
memories.push(memory);
|
||
|
storages.push(storage);
|
||
|
return node;
|
||
|
}
|
||
|
|
||
|
function getPeer(node) {
|
||
|
const peers = nodes.filter((peer) => peer !== node);
|
||
|
const idx = Math.floor(Math.random() * peers.length);
|
||
|
return peers[idx];
|
||
|
}
|
||
|
|
||
|
addNode();
|
||
|
addNode();
|
||
|
|
||
|
const [
|
||
|
seekTruth,
|
||
|
considerInfo,
|
||
|
evaluateConfidence,
|
||
|
chooseResponse,
|
||
|
qualifiedOpinions,
|
||
|
requestMemoryData,
|
||
|
memoryData,
|
||
|
requestStorageData,
|
||
|
storageData,
|
||
|
] = [
|
||
|
"seek truth",
|
||
|
"consider available information",
|
||
|
"evaluate confidence",
|
||
|
"choose response",
|
||
|
"qualified opinions",
|
||
|
"request in-memory data",
|
||
|
"in-memory data",
|
||
|
"request storage data",
|
||
|
"storage data",
|
||
|
].map((name) => scene.addAction(name));
|
||
|
|
||
|
memories.forEach((memory) => {
|
||
|
memory.setStatus("Idle");
|
||
|
memory.on(requestMemoryData, async (src, _detail) => {
|
||
|
memory.setStatus("Retrieving data");
|
||
|
await delay(1000);
|
||
|
memory.send(src, memoryData, {});
|
||
|
memory.setStatus("Idle");
|
||
|
});
|
||
|
});
|
||
|
|
||
|
storages.forEach((storage) => {
|
||
|
storage.setStatus("Idle");
|
||
|
storage.on(requestStorageData, async (src, _detail) => {
|
||
|
storage.setStatus("Retrieving data");
|
||
|
await delay(1000);
|
||
|
storage.send(src, storageData, {});
|
||
|
storage.setStatus("Idle");
|
||
|
});
|
||
|
});
|
||
|
|
||
|
nodes.forEach((node) => {
|
||
|
node.setStatus("Idle");
|
||
|
node.on(seekTruth, async (seeker, detail) => {
|
||
|
node.setStatus("Processing request");
|
||
|
|
||
|
node.on(chooseResponse, async (_src, _info) => {
|
||
|
node.setStatus("Choosing response");
|
||
|
await delay(1000);
|
||
|
node.send(seeker, qualifiedOpinions, {});
|
||
|
node.setStatus("Idle");
|
||
|
});
|
||
|
|
||
|
node.on(evaluateConfidence, async (_src, _info) => {
|
||
|
node.setStatus("Evaluating confidence");
|
||
|
await delay(1000);
|
||
|
node.send(node, chooseResponse);
|
||
|
});
|
||
|
|
||
|
node.on(considerInfo, async (_src, _info) => {
|
||
|
node.setStatus("Considering info");
|
||
|
await delay(1000);
|
||
|
node.send(node, evaluateConfidence);
|
||
|
});
|
||
|
|
||
|
node.on(memoryData, (_src, _data) => {
|
||
|
node.on(storageData, (__src, __data) => {
|
||
|
if (detail?.readConcern === "single") {
|
||
|
node.send(node, considerInfo, {});
|
||
|
} else {
|
||
|
const peer = getPeer(node);
|
||
|
node.on(qualifiedOpinions, (___src, info) => {
|
||
|
node.send(node, considerInfo, info);
|
||
|
});
|
||
|
node.send(peer, seekTruth, { readConcern: "single" });
|
||
|
}
|
||
|
});
|
||
|
node.send(node.storage, requestStorageData);
|
||
|
});
|
||
|
|
||
|
await delay(1000);
|
||
|
node.send(node.memory, requestMemoryData);
|
||
|
});
|
||
|
});
|
||
|
|
||
|
webClient.on(qualifiedOpinions, (_src, _detail) => {
|
||
|
webClient.setStatus("Received opinions and qualifications");
|
||
|
});
|
||
|
|
||
|
await delay(1000);
|
||
|
webClient.setStatus("Seek truth");
|
||
|
webClient.send(nodes[0], seekTruth);
|
||
|
})();
|
||
|
</script>
|