[APM] fixes infinite recursion for multiple waterfall item references (#29659)

* [APM] fixes #29564 by bailing out of recursion when a multiple references of the same object are detected

* [APM] minimized test fixure to isolate logic being tested

* [APM] improve readabilty by using better var name
This commit is contained in:
Oliver Gupte 2019-01-30 16:01:12 -08:00 committed by GitHub
parent 46c6f11a1f
commit 8cc8679355
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 43 additions and 0 deletions

View file

@ -1,5 +1,29 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`waterfall_helpers getWaterfallItems should handle cyclic references 1`] = `
Array [
Object {
"childIds": Array [
"a",
],
"id": "a",
"offset": 0,
"skew": 0,
"timestamp": 10,
},
Object {
"childIds": Array [
"a",
],
"id": "a",
"offset": 10,
"parentId": "a",
"skew": undefined,
"timestamp": 20,
},
]
`;
exports[`waterfall_helpers getWaterfallItems should order items correctly 1`] = `
Array [
Object {

View file

@ -98,6 +98,20 @@ describe('waterfall_helpers', () => {
getWaterfallItems(childrenByParentId, entryTransactionItem)
).toMatchSnapshot();
});
it('should handle cyclic references', () => {
const items = [
{ id: 'a', timestamp: 10 } as IWaterfallItem,
{ id: 'a', parentId: 'a', timestamp: 20 } as IWaterfallItem
];
const childrenByParentId = groupBy(items, hit =>
hit.parentId ? hit.parentId : 'root'
);
const entryTransactionItem = childrenByParentId.root[0];
expect(
getWaterfallItems(childrenByParentId, entryTransactionItem)
).toMatchSnapshot();
});
});
describe('getClockSkew', () => {

View file

@ -185,10 +185,15 @@ export function getWaterfallItems(
childrenByParentId: IWaterfallGroup,
entryTransactionItem: IWaterfallItem
) {
const visitedWaterfallItemSet = new Set();
function getSortedChildren(
item: IWaterfallItem,
parentItem?: IWaterfallItem
): IWaterfallItem[] {
if (visitedWaterfallItemSet.has(item)) {
return [];
}
visitedWaterfallItemSet.add(item);
const children = sortBy(childrenByParentId[item.id] || [], 'timestamp');
item.childIds = children.map(child => child.id);