Skip to content

Commit 2388228

Browse files
committed
fix: improve performance of dashboard replay
1 parent 0bf9ead commit 2388228

File tree

3 files changed

+44
-27
lines changed
  • plugins/plugin-codeflare-dashboard/src

3 files changed

+44
-27
lines changed

Diff for: plugins/plugin-codeflare-dashboard/src/components/Dashboard/index.tsx

+34-16
Original file line numberDiff line numberDiff line change
@@ -80,23 +80,41 @@ export default class Dashboard extends React.PureComponent<Props, State> {
8080
}
8181
}
8282

83-
/** We have received an update from `this.props.initWatcher` */
83+
/** Helps with debouncing updates of WorkersUpdate */
84+
private updateDebounce1: (null | ReturnType<typeof setTimeout>)[] = []
85+
86+
/** Helps with debouncing updates of LogLineUpdate */
87+
private updateDebounce2: (null | ReturnType<typeof setTimeout>)[] = []
88+
89+
/** We have received an update from a `GridSpec.initWatcher` */
8490
private readonly onUpdate = (gridIdx: number, model: UpdatePayload) => {
85-
this.setState((curState) => ({
86-
firstUpdate: (curState && curState.firstUpdate) || Date.now(), // TODO pull from the events
87-
lastUpdate: Date.now(), // TODO pull from the events
88-
events: !isWorkersUpdate(model)
89-
? curState?.events
90-
: !model.events || model.events.length === 0
91-
? curState?.events
92-
: model.events,
93-
logLine: !isWorkersUpdate(model) ? model.logLine : curState?.logLine,
94-
workers: !isWorkersUpdate(model)
95-
? curState?.workers
96-
: !curState?.workers
97-
? [model.workers]
98-
: [...curState.workers.slice(0, gridIdx), model.workers, ...curState.workers.slice(gridIdx + 1)],
99-
}))
91+
// to avoid a flurry of renders, we do some debouncing here
92+
const bouncies = isWorkersUpdate(model) ? this.updateDebounce1 : this.updateDebounce2
93+
const bouncey = bouncies[gridIdx]
94+
if (bouncey !== null) clearTimeout(bouncey)
95+
96+
bouncies[gridIdx] = setTimeout(
97+
() =>
98+
this.setState((curState) => ({
99+
lastUpdate: Date.now(), // TODO pull from the events
100+
firstUpdate: (curState && curState.firstUpdate) || Date.now(), // TODO pull from the events
101+
102+
logLine: !isWorkersUpdate(model) ? model.logLine : curState?.logLine,
103+
104+
events: !isWorkersUpdate(model)
105+
? curState?.events
106+
: !model.events || model.events.length === 0
107+
? curState?.events
108+
: model.events,
109+
110+
workers: !isWorkersUpdate(model)
111+
? curState?.workers
112+
: !curState?.workers
113+
? [model.workers]
114+
: [...curState.workers.slice(0, gridIdx), model.workers, ...curState.workers.slice(gridIdx + 1)],
115+
})),
116+
0
117+
)
100118
}
101119

102120
/** @return the grid models, excluding the `null` linebreak indicators */

Diff for: plugins/plugin-codeflare-dashboard/src/controller/dashboard/status/Live.ts

+1-5
Original file line numberDiff line numberDiff line change
@@ -181,16 +181,12 @@ export default class Live {
181181
}
182182
}
183183

184-
/** Helps with debouncing logLine updates */
185-
private logLineTO: null | ReturnType<typeof setTimeout> = null
186-
187184
/** Add the given `line` to our logLines model and pass the updated model to `cb` */
188185
private pushLineAndPublish(logLine: string, cb: OnData) {
189186
if (logLine) {
190187
// here we avoid a flood of React renders by batching them up a
191188
// bit; i thought react 18 was supposed to help with this. hmm.
192-
if (this.logLineTO) clearTimeout(this.logLineTO)
193-
this.logLineTO = setTimeout(() => cb({ logLine }), 1)
189+
cb({ logLine })
194190
}
195191
}
196192

Diff for: plugins/plugin-codeflare-dashboard/src/controller/dashboard/utilization/Live.ts

+9-6
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,10 @@ export default class Live {
5151
) {
5252
tails.map((tailf) => {
5353
tailf.then(({ stream }) => {
54-
stream.on("data", (data) => {
54+
// async here to improve interleaving (i.e. the async is used
55+
// to introduce a thread yield), not because we have anything
56+
// inherently asynchronous to do
57+
stream.on("data", async (data) => {
5558
if (data) {
5659
const line = stripAnsi(data)
5760
const cols = line.split(/\s+/)
@@ -115,11 +118,6 @@ export default class Live {
115118
// out of date event, drop it
116119
return
117120
}
118-
119-
// inform the UI that we have updates
120-
cb({
121-
workers: Object.values(this.workers),
122-
})
123121
}
124122

125123
if (name === "*") {
@@ -129,6 +127,11 @@ export default class Live {
129127
// this event affects a specific worker
130128
update(name)
131129
}
130+
131+
// inform the UI that we have updates
132+
cb({
133+
workers: Object.values(this.workers),
134+
})
132135
}
133136
}
134137
})

0 commit comments

Comments
 (0)