From 7290594d4c561531664c061f34491016c143564c Mon Sep 17 00:00:00 2001 From: Ivan Velev Date: Sat, 5 Feb 2022 15:39:18 -0800 Subject: [PATCH] added CDX Loader simulator updates; removed from default index file --- pywb/vueui/src/cdx-simulator/README.md | 41 ++++++++++++++++++ pywb/vueui/src/cdx-simulator/cdx-simulator.js | 31 ++++++------- .../pywb-vueui-cdx-simulator-config.jpg | Bin 0 -> 30987 bytes pywb/vueui/src/index.js | 3 -- 4 files changed, 54 insertions(+), 21 deletions(-) create mode 100644 pywb/vueui/src/cdx-simulator/README.md create mode 100644 pywb/vueui/src/cdx-simulator/pywb-vueui-cdx-simulator-config.jpg diff --git a/pywb/vueui/src/cdx-simulator/README.md b/pywb/vueui/src/cdx-simulator/README.md new file mode 100644 index 00000000..b9a4a7be --- /dev/null +++ b/pywb/vueui/src/cdx-simulator/README.md @@ -0,0 +1,41 @@ +# How to incorporate CDX Simulator + +Place following code snippets in **index.js** + +## Import `CDXQueryWorkerSimulator` Mock Class + +It is the mock class to the main javascript built-in `Worker` class: + + ``import { CDXQueryWorkerSimulator } from "./cdx-simulator/cdx-simulator";`` + +## Initialize `queryWorker` with Mock Class + +Update `const queryWorker = ...` initialization in `CDXLoader` class, `loadCDX()` method + +### by replacing it + +``` +const queryWorker = new CDXQueryWorkerSimulator(this.staticPrefix + "/queryWorker.js"); +``` + +### or by adding a conditional, so you can go back and forth between simulator and real CDX-data-loader: + +for example with a URL-hash flag conditional: + +``` +const queryWorker = new (window.location.hash.indexOf('cdx_simulate') >= 0 ? CDXQueryWorkerSimulator : Worker)(this.staticPrefix + "/queryWorker.js"); +``` + +NOTE: where if the url contains '#cdx_simulate' the mock simulator will be used; using a URL hash does not interfere with the main URL parsing of the PYWB app + +## Configure Simulation + +Add a **local** storage (from Chrome Dev Tools > Application > Local Storage) + +``` +{"count":5000, "yearStart":2020, "yearEnd":2022, "fetchTime":3000} +``` + +where `count` is the total records, yearStart and yearEnd are self-explanatory, and `fetchTime` is how long it should take + +![cdx loader config](pywb-vueui-cdx-simulator-config.jpg) \ No newline at end of file diff --git a/pywb/vueui/src/cdx-simulator/cdx-simulator.js b/pywb/vueui/src/cdx-simulator/cdx-simulator.js index 42d225d6..5527fed3 100644 --- a/pywb/vueui/src/cdx-simulator/cdx-simulator.js +++ b/pywb/vueui/src/cdx-simulator/cdx-simulator.js @@ -23,14 +23,7 @@ class CDXRecordFactory { // exaggerate max count per day, any day can hold up to 10th of the month's captures const maxPerDay = avgPerMonth/10; - let avgTimePerRecord = opts.fetchTime/total; // e.g. 1000 ms / 10,000 - let waitAtEveryNRecords = 1; - if (avgTimePerRecord < 1) { // < 1ms per records - waitAtEveryNRecords = Math.ceil(1/avgTimePerRecord); // invert - avgTimePerRecord = 1; - } else { // >= 1ms per record - avgTimePerRecord = Math.round(avgTimePerRecord); - } + let startTime = Math.floor(new Date().getTime()); let recordI = 0; for(let y=years[0]; y<=years[1]; y++) { @@ -42,23 +35,25 @@ class CDXRecordFactory { const times = {}; // make sure we save to hash to de-dupe for(let i=0; i { - setTimeout(() => { - resolve(true); - }, avgTimePerRecord); - }); - await p; - } - const newTime = Math.floor(Math.random()*3600*24); + const newTime = [Math.floor(Math.random()*24), Math.floor(Math.random()*60), Math.floor(Math.random()*60)].join(''); times[newTime] = 1; } Object.keys(times).sort().forEach(time => { - records.push({url, timestamp: dayTimestampPrefix+('000000'+time).substr(-6)}); + records.push({url, timestamp: dayTimestampPrefix+time}); }); } } } + let endTime = Math.floor(new Date().getTime()); + + if (opts.fetchTime && opts.fetchTime > endTime - startTime) { // wait till we reac fetchTime + const p = new Promise((resolve) => { + setTimeout(() => { + resolve(true); + }, (opts.fetchTime - (endTime - startTime))); + }); + await p; + } return records; } } diff --git a/pywb/vueui/src/cdx-simulator/pywb-vueui-cdx-simulator-config.jpg b/pywb/vueui/src/cdx-simulator/pywb-vueui-cdx-simulator-config.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e8a513b2058495e30dc0ef21d7f8b27a8c1a5ebe GIT binary patch literal 30987 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 {