change(ui) - player fixes from dev (#1165)

* conflicts from 72be865c5f

* fix(player): priority and await for message processing

---------

Co-authored-by: nick-delirium <nikita@openreplay.com>
This commit is contained in:
Shekar Siri 2023-04-13 18:29:55 +02:00 committed by GitHub
parent be4e16901a
commit 7021eec51c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 72 additions and 45 deletions

View file

@ -44,7 +44,7 @@ export default observer(({ player }) => {
<Performance
performanceChartTime={ current ? current.tmie : 0 }
performanceChartData={ player.lists[PERFORMANCE].list }
avaliability={ player.lists[PERFORMANCE].availability }
availability={ player.lists[PERFORMANCE].availability }
hiddenScreenMarker={ false }
player={ player }
/>

View file

@ -220,12 +220,12 @@ export default class Performance extends React.PureComponent {
render() {
const {
performanceChartTime,
avaliability = {},
availability = {},
hiddenScreenMarker = true,
} = this.props;
const { fps, cpu, heap, nodes, memory, battery } = avaliability;
const avaliableCount = [ fps, cpu, heap, nodes, memory, battery ].reduce((c, av) => av ? c + 1 : c, 0);
const height = avaliableCount === 0 ? "0" : `${100 / avaliableCount}%`;
const { fps, cpu, heap, nodes, memory, battery } = availability;
const availableCount = [ fps, cpu, heap, nodes, memory, battery ].reduce((c, av) => av ? c + 1 : c, 0);
const height = availableCount === 0 ? "0" : `${100 / availableCount}%`;
return (
<>

View file

@ -187,7 +187,7 @@ function Performance({
performanceChartData,
connType,
connBandwidth,
performanceAvaliability: avaliability,
performanceAvailability: availability,
} = store.get();
React.useState(() => {
@ -212,9 +212,9 @@ function Performance({
}
};
const { fps, cpu, heap, nodes } = avaliability;
const avaliableCount = [fps, cpu, heap, nodes].reduce((c, av) => (av ? c + 1 : c), 0);
const height = avaliableCount === 0 ? '0' : `${100 / avaliableCount}%`;
const { fps, cpu, heap, nodes } = availability;
const availableCount = [fps, cpu, heap, nodes].reduce((c, av) => (av ? c + 1 : c), 0);
const height = availableCount === 0 ? '0' : `${100 / availableCount}%`;
return (
<BottomBlock>

View file

@ -52,7 +52,7 @@ export interface State extends ScreenState, ListsState {
connBandwidth?: number,
location?: string,
performanceChartTime?: number,
performanceAvaliability?: PerformanceTrackManager['avaliability']
performanceAvailability?: PerformanceTrackManager['availability']
domContentLoadedTime?: { time: number, value: number },
domBuildingTime?: number,
@ -191,7 +191,7 @@ export default class MessageManager {
private onFileReadSuccess = () => {
const stateToUpdate : Partial<State>= {
performanceChartData: this.performanceTrackManager.chartData,
performanceAvaliability: this.performanceTrackManager.avaliability,
performanceAvailability: this.performanceTrackManager.availability,
...this.lists.getFullListsState(),
}
if (this.activityManager) {
@ -214,7 +214,7 @@ export default class MessageManager {
async loadMessages(isClickmap: boolean = false) {
this.setMessagesLoading(true)
// TODO: reusable decryptor instance
const createNewParser = (shouldDecrypt = true, file) => {
const createNewParser = (shouldDecrypt = true, file?: string) => {
const decrypt = shouldDecrypt && this.session.fileKey
? (b: Uint8Array) => decryptSessionBytes(b, this.session.fileKey)
: (b: Uint8Array) => Promise.resolve(b)
@ -228,7 +228,7 @@ export default class MessageManager {
}
const sorted = msgs.sort((m1, m2) => {
// @ts-ignore
if (m1.time === m2.time) return m1._index - m2._index
if (!m1.time || !m2.time || m1.time === m2.time) return m1._index - m2._index
return m1.time - m2.time
})
@ -250,34 +250,60 @@ export default class MessageManager {
this.waitingForFiles = true
// TODO: refactor this stuff; split everything to async/await
const loadMethod = this.session.domURL && this.session.domURL.length > 0
? { url: this.session.domURL, parser: () => createNewParser(true, 'dom') }
: { url: this.session.mobsUrl, parser: () => createNewParser(false, 'dom')}
loadFiles(loadMethod.url, loadMethod.parser())
// EFS fallback
.catch((e) =>
requestEFSDom(this.session.sessionId)
.then(createNewParser(false, 'domEFS'))
const parser = loadMethod.parser()
/**
* We load first dom mobfile before the rest
* to speed up time to replay
* but as a tradeoff we have to have some copy-paste
* for the devtools file
* */
loadFiles([loadMethod.url[0]], parser)
.then(() => {
const domPromise = loadMethod.url.length > 1
? loadFiles([loadMethod.url[1]], parser, true)
: Promise.resolve()
const devtoolsPromise = !isClickmap
? this.loadDevtools(createNewParser)
: Promise.resolve()
return Promise.all([domPromise, devtoolsPromise])
})
/**
* EFS fallback for unprocessed sessions (which are live)
* */
.catch(() => {
requestEFSDom(this.session.sessionId)
.then(createNewParser(false, 'domEFS'))
.catch(this.onFileReadFailed)
if (!isClickmap) {
this.loadDevtools(createNewParser)
}
}
)
.then(this.onFileReadSuccess)
.catch(this.onFileReadFailed)
.finally(this.onFileReadFinally);
}
// load devtools (TODO: start after the first DOM file download)
if (isClickmap) return;
loadDevtools(createNewParser: (shouldDecrypt: boolean, file: string) => (b: Uint8Array) => Promise<void>) {
this.state.update({ devtoolsLoading: true })
loadFiles(this.session.devtoolsURL, createNewParser(true, 'devtools'))
// EFS fallback
.catch(() =>
requestEFSDevtools(this.session.sessionId)
.then(createNewParser(false, 'devtoolsEFS'))
)
.then(() => {
this.state.update(this.lists.getFullListsState()) // TODO: also in case of dynamic update through assist
})
.catch(e => logger.error("Can not download the devtools file", e))
.finally(() => this.state.update({ devtoolsLoading: false }))
return loadFiles(this.session.devtoolsURL, createNewParser(true, 'devtools'))
// EFS fallback
.catch(() =>
requestEFSDevtools(this.session.sessionId)
.then(createNewParser(false, 'devtoolsEFS'))
)
// TODO: also in case of dynamic update through assist
.then(() => {
this.state.update({ ...this.lists.getFullListsState() })
})
.catch(e => logger.error("Can not download the devtools file", e))
.finally(() => this.state.update({ devtoolsLoading: false }))
}
resetMessageManagers() {

View file

@ -15,9 +15,9 @@ export default class PerformanceTrackManager extends ListWalker<PerformanceTrack
private chart: Array<PerformanceChartPoint> = [];
private isHidden: boolean = false;
private timeCorrection: number = 0;
private heapAvaliable: boolean = false;
private fpsAvaliable: boolean = false;
private cpuAvaliable: boolean = false;
private heapAvailable: boolean = false;
private fpsAvailable: boolean = false;
private cpuAvailable: boolean = false;
private prevTime: number | null = null;
private prevNodesCount: number = 0;
@ -29,7 +29,7 @@ export default class PerformanceTrackManager extends ListWalker<PerformanceTrack
let timePassed = msg.time - this.prevTime + this.timeCorrection;
if (timePassed > 0 && msg.frames >= 0) {
if (msg.frames > 0) { this.fpsAvaliable = true; }
if (msg.frames > 0) { this.fpsAvailable = true; }
fps = msg.frames*1e3/timePassed; // Multiply by 1e3 as time in ms;
fps = Math.min(fps,60); // What if 120? TODO: alert if more than 60
if (this.chart.length === 1) {
@ -38,7 +38,7 @@ export default class PerformanceTrackManager extends ListWalker<PerformanceTrack
}
if (timePassed > 0 && msg.ticks >= 0) {
this.cpuAvaliable = true;
this.cpuAvailable = true;
let tickRate = msg.ticks * 30 / timePassed;
if (tickRate > 1) {
tickRate = 1;
@ -53,7 +53,7 @@ export default class PerformanceTrackManager extends ListWalker<PerformanceTrack
this.prevTime = msg.time;
this.timeCorrection = 0
this.heapAvaliable = this.heapAvaliable || msg.usedJSHeapSize > 0;
this.heapAvailable = this.heapAvailable || msg.usedJSHeapSize > 0;
this.chart.push({
usedHeap: msg.usedJSHeapSize,
totalHeap: msg.totalJSHeapSize,
@ -109,11 +109,11 @@ export default class PerformanceTrackManager extends ListWalker<PerformanceTrack
return this.chart;
}
get avaliability(): { cpu: boolean, fps: boolean, heap: boolean, nodes: boolean } {
get availability(): { cpu: boolean, fps: boolean, heap: boolean, nodes: boolean } {
return {
cpu: this.cpuAvaliable,
fps: this.fpsAvaliable,
heap: this.heapAvaliable,
cpu: this.cpuAvailable,
fps: this.fpsAvailable,
heap: this.heapAvailable,
nodes: true,
}
}

View file

@ -8,15 +8,16 @@ export const NO_URLS = 'No-urls-provided'
export async function loadFiles(
urls: string[],
onData: (data: Uint8Array) => void,
): Promise<any> {
canSkip: boolean = false,
): Promise<void> {
if (!urls.length) {
throw NO_URLS
}
try {
for (let url of urls) {
const response = await window.fetch(url)
const data = await processAPIStreamResponse(response, url !== url[0])
onData(data)
const data = await processAPIStreamResponse(response, urls.length > 1 ? url !== urls[0] : canSkip)
await onData(data)
}
} catch(e) {
if (e === ALLOWED_404) {