Show download progress and cancel request on unmount (#46)
* Improve loading feedback * Add ms metric * Add download progress and ability to cancel fetch
This commit is contained in:
parent
9652b33e4d
commit
14e21702aa
|
@ -12,7 +12,7 @@
|
|||
"antd": "^4.15.0",
|
||||
"electron-squirrel-startup": "^1.0.0",
|
||||
"js-yaml": "^4.0.0 ",
|
||||
"mlg-converter": "^0.4.0",
|
||||
"mlg-converter": "^0.5.0",
|
||||
"parsimmon": "^1.16.0",
|
||||
"react": "^17.0.1",
|
||||
"react-dom": "^17.0.2",
|
||||
|
@ -15534,9 +15534,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/mlg-converter": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/mlg-converter/-/mlg-converter-0.4.0.tgz",
|
||||
"integrity": "sha512-lWO5KYOpGogrW8bqAfFTQU+22g4LnCehGf7ZiFfMOfu/S0Rt5t9ZIlHYAOi3Qh79qoDnD1hk/oMXhKRouagI0w=="
|
||||
"version": "0.5.0",
|
||||
"resolved": "https://registry.npmjs.org/mlg-converter/-/mlg-converter-0.5.0.tgz",
|
||||
"integrity": "sha512-FKqJ0vbbxFZuziwMbih8fRF8JFF2xFSWmYNOylji1IkRPu83dCWCGV4AkG9fkKs/z9ThOqfuSkaUEnWbL33c8g=="
|
||||
},
|
||||
"node_modules/moment": {
|
||||
"version": "2.29.1",
|
||||
|
@ -38513,9 +38513,9 @@
|
|||
}
|
||||
},
|
||||
"mlg-converter": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/mlg-converter/-/mlg-converter-0.4.0.tgz",
|
||||
"integrity": "sha512-lWO5KYOpGogrW8bqAfFTQU+22g4LnCehGf7ZiFfMOfu/S0Rt5t9ZIlHYAOi3Qh79qoDnD1hk/oMXhKRouagI0w=="
|
||||
"version": "0.5.0",
|
||||
"resolved": "https://registry.npmjs.org/mlg-converter/-/mlg-converter-0.5.0.tgz",
|
||||
"integrity": "sha512-FKqJ0vbbxFZuziwMbih8fRF8JFF2xFSWmYNOylji1IkRPu83dCWCGV4AkG9fkKs/z9ThOqfuSkaUEnWbL33c8g=="
|
||||
},
|
||||
"moment": {
|
||||
"version": "2.29.1",
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
"antd": "^4.15.0",
|
||||
"electron-squirrel-startup": "^1.0.0",
|
||||
"js-yaml": "^4.0.0 ",
|
||||
"mlg-converter": "^0.4.0",
|
||||
"mlg-converter": "^0.5.0",
|
||||
"parsimmon": "^1.16.0",
|
||||
"react": "^17.0.1",
|
||||
"react-dom": "^17.0.2",
|
||||
|
|
Binary file not shown.
|
@ -26,7 +26,7 @@ import useBreakpoint from 'antd/lib/grid/hooks/useBreakpoint';
|
|||
import { connect } from 'react-redux';
|
||||
import {
|
||||
Field,
|
||||
Result as ParserResult,
|
||||
Result as ParserResult,
|
||||
} from 'mlg-converter/dist/types';
|
||||
import PerfectScrollbar from 'react-perfect-scrollbar';
|
||||
// eslint-disable-next-line import/no-unresolved
|
||||
|
@ -35,13 +35,13 @@ import { loadLogs } from '../utils/api';
|
|||
import Canvas, { LogEntry } from './Log/Canvas';
|
||||
import {
|
||||
AppState,
|
||||
UIState,
|
||||
UIState,
|
||||
} from '../types/state';
|
||||
import { Config } from '../types/config';
|
||||
import store from '../store';
|
||||
import {
|
||||
formatBytes,
|
||||
msToTime,
|
||||
msToTime,
|
||||
} from '../utils/number';
|
||||
|
||||
const { TabPane } = Tabs;
|
||||
|
@ -89,9 +89,13 @@ const Log = ({ ui, config }: { ui: UIState, config: Config }) => {
|
|||
|
||||
useEffect(() => {
|
||||
const worker = new MlgParserWorker();
|
||||
const controller = new AbortController();
|
||||
const { signal } = controller;
|
||||
const loadData = async () => {
|
||||
const raw = await loadLogs();
|
||||
setFileSize(formatBytes(raw.byteLength));
|
||||
const raw = await loadLogs((percent, total) => {
|
||||
setProgress(percent);
|
||||
setFileSize(formatBytes(total));
|
||||
}, signal);
|
||||
|
||||
worker.postMessage(raw);
|
||||
worker.onmessage = ({ data }) => {
|
||||
|
@ -99,15 +103,17 @@ const Log = ({ ui, config }: { ui: UIState, config: Config }) => {
|
|||
case 'progress':
|
||||
setStep(1);
|
||||
setProgress(data.progress);
|
||||
setParseElapsed(msToTime(data.elapsed));
|
||||
break;
|
||||
case 'result':
|
||||
setSamplesCount(data.result.records.length);
|
||||
setStep(2);
|
||||
setLogs(data.result);
|
||||
setFields(data.result.fields);
|
||||
break;
|
||||
case 'metrics':
|
||||
setParseElapsed(msToTime(data.metrics.elapsedMs));
|
||||
console.log(`Log parsed in ${data.elapsed}ms`);
|
||||
setParseElapsed(msToTime(data.elapsed));
|
||||
setSamplesCount(data.records);
|
||||
setStep(2);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -121,8 +127,9 @@ const Log = ({ ui, config }: { ui: UIState, config: Config }) => {
|
|||
window.addEventListener('resize', calculateCanvasWidth);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener('resize', calculateCanvasWidth);
|
||||
controller.abort();
|
||||
worker.terminate();
|
||||
window.removeEventListener('resize', calculateCanvasWidth);
|
||||
};
|
||||
}, [calculateCanvasWidth]);
|
||||
|
||||
|
|
|
@ -3,6 +3,10 @@ import { Config as ConfigType } from '../types/config';
|
|||
import stdDialogs from '../data/standardDialogs';
|
||||
import help from '../data/help';
|
||||
import { divider } from '../data/constants';
|
||||
import {
|
||||
fetchWithProgress,
|
||||
onProgress as onProgressType,
|
||||
} from './http';
|
||||
|
||||
export const loadAll = async () => {
|
||||
const started = new Date();
|
||||
|
@ -74,4 +78,5 @@ export const loadAll = async () => {
|
|||
});
|
||||
};
|
||||
|
||||
export const loadLogs = () => fetch('./logs/middle.mlg').then((response) => response.arrayBuffer());
|
||||
export const loadLogs = (onProgress?: onProgressType, signal?: AbortSignal) => fetchWithProgress('./logs/long.mlg', onProgress, signal)
|
||||
.then((response) => response.buffer);
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
export type onProgress = (percent: number, total: number) => void;
|
||||
|
||||
export const fetchWithProgress = async (url: string, onProgress?: onProgress, signal?: AbortSignal): Promise<Uint8Array> => {
|
||||
const response = await fetch(url, { signal });
|
||||
const contentLength = response.headers.get('Content-Length');
|
||||
|
||||
if (!contentLength) {
|
||||
throw new Error('Missing Content-Length while fetching');
|
||||
}
|
||||
|
||||
const reader = response.body!.getReader();
|
||||
const length = Number(contentLength);
|
||||
const array = new Uint8Array(length);
|
||||
|
||||
let at = 0;
|
||||
for (; ;) {
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
const { done, value } = await reader.read();
|
||||
|
||||
if (done) {
|
||||
break;
|
||||
}
|
||||
|
||||
array.set(value as Uint8Array, at);
|
||||
at += (value as Uint8Array).length;
|
||||
|
||||
if (onProgress) {
|
||||
// eslint-disable-next-line no-bitwise
|
||||
onProgress(~~(at / length * 100), length);
|
||||
}
|
||||
}
|
||||
|
||||
return array;
|
||||
};
|
|
@ -1,3 +1,4 @@
|
|||
/* eslint-disable no-bitwise */
|
||||
import { Parser } from 'mlg-converter';
|
||||
|
||||
// eslint-disable-next-line no-restricted-globals
|
||||
|
@ -10,13 +11,13 @@ ctx.addEventListener('message', ({ data }: { data: ArrayBuffer }) => {
|
|||
ctx.postMessage({
|
||||
type: 'progress',
|
||||
progress,
|
||||
elapsed: ~~(performance.now() - t0),
|
||||
});
|
||||
});
|
||||
ctx.postMessage({
|
||||
type: 'metrics',
|
||||
metrics: {
|
||||
elapsedMs: Math.round(performance.now() - t0),
|
||||
},
|
||||
elapsed: ~~(performance.now() - t0),
|
||||
records: result.records.length,
|
||||
});
|
||||
ctx.postMessage({ type: 'result', result });
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue