mirror of
https://github.com/gchq/CyberChef.git
synced 2025-04-24 00:36:16 -04:00
Added fine-grain timing for aspects of the bake. Improved efficiency of autobakes and moved output decoding into a worker.
This commit is contained in:
parent
84f0750525
commit
0b2cb7e68c
9 changed files with 287 additions and 57 deletions
145
src/web/waiters/TimingWaiter.mjs
Normal file
145
src/web/waiters/TimingWaiter.mjs
Normal file
|
@ -0,0 +1,145 @@
|
|||
/**
|
||||
* @author n1474335 [n1474335@gmail.com]
|
||||
* @copyright Crown Copyright 2023
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Waiter to handle timing of the baking process.
|
||||
*/
|
||||
class TimingWaiter {
|
||||
|
||||
/**
|
||||
* TimingWaiter constructor.
|
||||
*
|
||||
* @param {App} app - The main view object for CyberChef.
|
||||
* @param {Manager} manager - The CyberChef event manager.
|
||||
*/
|
||||
constructor(app, manager) {
|
||||
this.app = app;
|
||||
this.manager = manager;
|
||||
|
||||
this.inputs = {};
|
||||
/*
|
||||
Inputs example:
|
||||
"1": {
|
||||
"inputEncodingStart": 0,
|
||||
"inputEncodingEnd": 0,
|
||||
"trigger": 0
|
||||
"chefWorkerTasked": 0,
|
||||
"bakeComplete": 0,
|
||||
"bakeDuration": 0,
|
||||
"settingOutput": 0,
|
||||
"outputDecodingStart": 0,
|
||||
"outputDecodingEnd": 0,
|
||||
"complete": 0
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Record the time for an input
|
||||
*
|
||||
* @param {string} event
|
||||
* @param {number} inputNum
|
||||
* @param {number} value
|
||||
*/
|
||||
recordTime(event, inputNum, value=Date.now()) {
|
||||
inputNum = inputNum.toString();
|
||||
if (!Object.keys(this.inputs).includes(inputNum)) {
|
||||
this.inputs[inputNum] = {};
|
||||
}
|
||||
log.debug(`Recording ${event} for input ${inputNum}`);
|
||||
this.inputs[inputNum][event] = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* The total time for a completed bake
|
||||
*
|
||||
* @param {number} inputNum
|
||||
* @returns {number}
|
||||
*/
|
||||
overallDuration(inputNum) {
|
||||
const input = this.inputs[inputNum.toString()];
|
||||
|
||||
// If this input has not been encoded yet, we cannot calculate a time
|
||||
if (!input ||
|
||||
!input.trigger ||
|
||||
!input.inputEncodingEnd ||
|
||||
!input.inputEncodingStart)
|
||||
return 0;
|
||||
|
||||
// input encoding can happen before a bake is triggered, so it is calculated separately
|
||||
const inputEncodingTotal = input.inputEncodingEnd - input.inputEncodingStart;
|
||||
|
||||
let total = 0;
|
||||
if (input.bakeComplete && input.bakeComplete > input.trigger)
|
||||
total = input.bakeComplete - input.trigger;
|
||||
|
||||
if (input.settingOutput && input.settingOutput > input.trigger)
|
||||
total = input.settingOutput - input.trigger;
|
||||
|
||||
if (input.outputDecodingStart && input.outputDecodingStart > input.trigger)
|
||||
total = input.outputDecodingStart - input.trigger;
|
||||
|
||||
if (input.outputDecodingEnd && input.outputDecodingEnd > input.trigger)
|
||||
total = input.outputDecodingEnd - input.trigger;
|
||||
|
||||
if (input.complete && input.complete > input.trigger)
|
||||
total = input.complete - input.trigger;
|
||||
|
||||
return total + inputEncodingTotal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints out the time between stages
|
||||
*
|
||||
* @param {number} inputNum
|
||||
* @returns {string}
|
||||
*/
|
||||
printStages(inputNum) {
|
||||
const input = this.inputs[inputNum.toString()];
|
||||
if (!input || !input.trigger) return "";
|
||||
this.logAllTimes(inputNum);
|
||||
|
||||
const total = this.overallDuration(inputNum),
|
||||
inputEncoding = input.inputEncodingEnd - input.inputEncodingStart,
|
||||
outputDecoding = input.outputDecodingEnd - input.outputDecodingStart,
|
||||
overhead = total - inputEncoding - outputDecoding - input.bakeDuration;
|
||||
|
||||
return `Input encoding: ${inputEncoding}ms
|
||||
Recipe duration: ${input.bakeDuration}ms
|
||||
Output decoding: ${outputDecoding}ms
|
||||
Threading overhead: ${overhead}ms
|
||||
Total: ${total}ms`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs every interval
|
||||
*
|
||||
* @param {number} inputNum
|
||||
*/
|
||||
logAllTimes(inputNum) {
|
||||
const input = this.inputs[inputNum.toString()];
|
||||
if (!input || !input.trigger) return;
|
||||
|
||||
try {
|
||||
log.debug(`Trigger: ${input.trigger}
|
||||
inputEncodingStart: ${input.inputEncodingStart} | ${input.inputEncodingStart - input.trigger}ms since trigger
|
||||
inputEncodingEnd: ${input.inputEncodingEnd} | ${input.inputEncodingEnd - input.inputEncodingStart}ms input encoding time
|
||||
chefWorkerTasked: ${input.chefWorkerTasked} | ${input.chefWorkerTasked - input.trigger}ms since trigger
|
||||
bakeDuration: | ${input.bakeDuration}ms duration in worker
|
||||
bakeComplete: ${input.bakeComplete} | ${input.bakeComplete - input.chefWorkerTasked}ms since worker tasked
|
||||
settingOutput: ${input.settingOutput} | ${input.settingOutput - input.bakeComplete}ms since worker finished
|
||||
outputDecodingStart: ${input.outputDecodingStart} | ${input.outputDecodingStart - input.settingOutput}ms since output set
|
||||
outputDecodingEnd: ${input.outputDecodingEnd} | ${input.outputDecodingEnd - input.outputDecodingStart}ms output encoding time
|
||||
complete: ${input.complete} | ${input.complete - input.outputDecodingEnd}ms since output decoded
|
||||
Total: | ${input.complete - input.trigger}ms since trigger`);
|
||||
} catch (err) {}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default TimingWaiter;
|
Loading…
Add table
Add a link
Reference in a new issue