Optimized stats aggregation code for Admin dashboard
fix https://linear.app/tryghost/issue/SLO-168/rangeerror-maximum-call-stack-size-exceeded - this code takes the API output and reduces it down to collect together stats per date - the current code is recursive, and we've seen errors with the recursion hitting a `RangeError: Maximum call stack size exceeded` error - as well as that, we're doing a lot of array concat'ing and cloning, which burns memory and CPU time - instead, we can just use `.reduce` - the new implementation is much faster than the existing one (1ms vs 85ms) and uses no recursion, so those errors should go away - I've also verified that the output is the same between the two functions
This commit is contained in:
parent
43bb83f7bb
commit
f250898a3b
@ -1,31 +1,26 @@
|
||||
export default function mergeDates(list, entry) {
|
||||
const [current, ...rest] = list;
|
||||
export default function mergeStatsByDate(list) {
|
||||
const reducedStatsByDate = list.reduce((acc, current) => {
|
||||
const currentDate = current.date;
|
||||
|
||||
if (!current) {
|
||||
return entry ? [entry] : [];
|
||||
}
|
||||
if (!acc[currentDate]) {
|
||||
acc[currentDate] = {
|
||||
date: currentDate,
|
||||
count: 0,
|
||||
positiveDelta: 0,
|
||||
negativeDelta: 0,
|
||||
signups: 0,
|
||||
cancellations: 0
|
||||
};
|
||||
}
|
||||
|
||||
if (!entry) {
|
||||
return mergeDates(rest, {
|
||||
date: current.date,
|
||||
count: current.count,
|
||||
positiveDelta: current.positive_delta,
|
||||
negativeDelta: current.negative_delta,
|
||||
signups: current.signups,
|
||||
cancellations: current.cancellations
|
||||
});
|
||||
}
|
||||
acc[currentDate].count += current.count;
|
||||
acc[currentDate].positiveDelta += current.positive_delta;
|
||||
acc[currentDate].negativeDelta += current.negative_delta;
|
||||
acc[currentDate].signups += current.signups;
|
||||
acc[currentDate].cancellations += current.cancellations;
|
||||
|
||||
if (current.date === entry.date) {
|
||||
return mergeDates(rest, {
|
||||
date: entry.date,
|
||||
count: entry.count + current.count,
|
||||
positiveDelta: entry.positiveDelta + current.positive_delta,
|
||||
negativeDelta: entry.negativeDelta + current.negative_delta,
|
||||
signups: entry.signups + current.signups,
|
||||
cancellations: entry.cancellations + current.cancellations
|
||||
});
|
||||
}
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
return [entry].concat(mergeDates(list));
|
||||
return Object.values(reducedStatsByDate);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user