Skip to content

Commit ea32e7c

Browse files
committed
Split baseline from polling
1 parent 7c4e858 commit ea32e7c

2 files changed

Lines changed: 78 additions & 42 deletions

File tree

src/features/flows/nRF54L15_cloud/evaluate/TestCrash.tsx

Lines changed: 63 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import { useAppDispatch, useAppSelector } from '../../../../app/store';
1212
import { Back } from '../../../../common/Back';
1313
import Main from '../../../../common/Main';
1414
import { Next, Skip } from '../../../../common/Next';
15-
import { pollCrashReport } from './api';
15+
import { fetchCrashBaseline, pollForNewCrash } from './api';
1616
import {
1717
getCrashReport,
1818
getCrashReportBaselineDate,
@@ -41,25 +41,49 @@ export default ({ vComIndex }: { vComIndex: number }) => {
4141
}
4242

4343
const controller = new AbortController();
44-
pollCrashReport(serialNumber, controller.signal, {
45-
baseline: crashReportBaselineDate,
46-
onBaseline: b => dispatch(setCrashReportBaselineDate(b)),
47-
})
48-
.then(crash => dispatch(setCrashReport(crash)))
49-
.catch(e => {
50-
if ((e as Error).name === 'AbortError') {
51-
return;
52-
}
53-
reportEvaluateError('Test crash', e, 'poll-crash');
54-
setError(describeError(e));
55-
});
44+
45+
if (crashReportBaselineDate === undefined) {
46+
// First establish the baseline: whatever crash exists now is old.
47+
fetchCrashBaseline(serialNumber, controller.signal)
48+
.then(b => dispatch(setCrashReportBaselineDate(b)))
49+
.catch(e => {
50+
if ((e as Error).name === 'AbortError') {
51+
return;
52+
}
53+
reportEvaluateError('Test crash', e, 'fetch-baseline');
54+
setError(describeError(e));
55+
});
56+
} else {
57+
pollForNewCrash(
58+
serialNumber,
59+
crashReportBaselineDate,
60+
controller.signal,
61+
)
62+
.then(crash => dispatch(setCrashReport(crash)))
63+
.catch(e => {
64+
if ((e as Error).name === 'AbortError') {
65+
return;
66+
}
67+
reportEvaluateError('Test crash', e, 'poll-crash');
68+
setError(describeError(e));
69+
});
70+
}
5671

5772
return () => controller.abort();
58-
// When the first poll establishes the baseline, the effect is triggered again and restarts the poll once (with the established baseline).
73+
// Once the baseline is established the effect re-runs and starts polling for a new crash.
5974
}, [dispatch, serialNumber, crashReport, error, crashReportBaselineDate]);
6075

76+
const preparingBaseline =
77+
deviceInfo.status === 'success' &&
78+
crashReportBaselineDate === undefined &&
79+
!crashReport &&
80+
!error;
81+
6182
const waitingForCrash =
62-
deviceInfo.status === 'success' && !crashReport && !error;
83+
deviceInfo.status === 'success' &&
84+
crashReportBaselineDate !== undefined &&
85+
!crashReport &&
86+
!error;
6387

6488
return (
6589
<Main>
@@ -69,17 +93,20 @@ export default ({ vComIndex }: { vComIndex: number }) => {
6993
fillHeight
7094
>
7195
<div className="tw-flex tw-flex-col tw-gap-4">
72-
<div className="tw-flex tw-flex-col tw-gap-1">
73-
<span>
74-
Trigger a test crash by pressing <b>Button 1</b>.
75-
</span>
76-
<span>
77-
Your device will fault, reboot, and disconnect from
78-
the app. You need to reconnect the device to the
79-
app, which will send the crash report to the cloud
80-
over Bluetooth LE.
81-
</span>
82-
</div>
96+
{!preparingBaseline && (
97+
<div className="tw-flex tw-flex-col tw-gap-1">
98+
<span>
99+
Trigger a test crash by pressing <b>Button 1</b>
100+
.
101+
</span>
102+
<span>
103+
Your device will fault, reboot, and disconnect
104+
from the app. You need to reconnect the device
105+
to the app, which will send the crash report to
106+
the cloud over Bluetooth LE.
107+
</span>
108+
</div>
109+
)}
83110

84111
{deviceInfo.status === 'loading' && (
85112
<div className="tw-flex tw-flex-row tw-items-center tw-gap-3">
@@ -90,6 +117,16 @@ export default ({ vComIndex }: { vComIndex: number }) => {
90117
</div>
91118
)}
92119

120+
{preparingBaseline && (
121+
<div className="tw-flex tw-flex-row tw-items-center tw-gap-3">
122+
<Spinner size="sm" />
123+
<span className="tw-text-xs">
124+
Syncronizing with the cloud to prepare to fetch
125+
a crash report.
126+
</span>
127+
</div>
128+
)}
129+
93130
{waitingForCrash && (
94131
<div className="tw-flex tw-flex-row tw-items-center tw-gap-3">
95132
<Spinner size="sm" />

src/features/flows/nRF54L15_cloud/evaluate/api.ts

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -74,11 +74,6 @@ interface FinalizeSymbolBody {
7474
};
7575
}
7676

77-
interface PollBaseline {
78-
baseline: string | null | undefined;
79-
onBaseline: (capturedDate: string | null) => void;
80-
}
81-
8277
const bearer = (token: string) => ({ Authorization: `Bearer ${token}` });
8378

8479
const mapCrash = ({
@@ -163,29 +158,33 @@ const fetchCrashReport = async (
163158
}
164159
};
165160

166-
export const pollCrashReport = (
161+
// The crash that exists now (if any) is old; its date is the baseline for new crashes.
162+
export const fetchCrashBaseline = async (
167163
deviceSerial: string,
168164
signal: AbortSignal,
169-
{ baseline, onBaseline }: PollBaseline,
165+
): Promise<string | null> => {
166+
const { status, crash } = await fetchCrashReport(deviceSerial, signal);
167+
const isTerminal = status === 'processed' || status === 'symbolicated';
168+
return isTerminal && crash ? crash.capturedDate : null;
169+
};
170+
171+
export const pollForNewCrash = (
172+
deviceSerial: string,
173+
baseline: string | null,
174+
signal: AbortSignal,
170175
intervalMs = POLL_INTERVAL_MS,
171176
): Promise<CrashReport> => {
172-
let current = baseline;
173-
174177
const attempt = async (): Promise<CrashReport> => {
175178
if (signal.aborted) {
176179
throw new DOMException('Aborted', 'AbortError');
177180
}
178181
const { status, crash } = await fetchCrashReport(deviceSerial, signal);
179182
const isTerminal = status === 'processed' || status === 'symbolicated';
180183

181-
if (current === undefined) {
182-
// The first request sets the baseline: the crash that exists now (if any) is old.
183-
current = isTerminal && crash ? crash.capturedDate : null;
184-
onBaseline(current);
185-
} else if (isTerminal && crash) {
184+
if (isTerminal && crash) {
186185
const isNew =
187-
current === null ||
188-
Date.parse(crash.capturedDate) > Date.parse(current);
186+
baseline === null ||
187+
Date.parse(crash.capturedDate) > Date.parse(baseline);
189188
if (isNew) {
190189
return crash;
191190
}

0 commit comments

Comments
 (0)