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>
 |