Skip to content

Commit

Permalink
Speed up Trace Statistics view calculation (#1941)
Browse files Browse the repository at this point in the history
## Which problem is this PR solving?
- Resolves #1925

## Description of the changes
- Speed up Trace Statistics view calculation. Now we precompute child
spans for each span to calculate statistics. Previously we filtered all
spans to find children for each span.

## How was this change tested?
- Existing tests. Ran manually on a large trace.

## Checklist
- [x] I have read
https://github.com/jaegertracing/jaeger/blob/master/CONTRIBUTING_GUIDELINES.md
- [x] I have signed all commits
- [x] I have added unit tests for the new functionality
- [x] I have run lint and test steps successfully
  - for `jaeger`: `make lint test`
  - for `jaeger-ui`: `yarn lint` and `yarn test`

---------

Signed-off-by: Maksim Gaponov <gaponovmaxev@gmail.com>
Signed-off-by: Maksim <gaponovmaxev@gmail.com>
Signed-off-by: Yuri Shkuro <github@ysh.us>
Co-authored-by: Yuri Shkuro <yurishkuro@users.noreply.github.com>
Co-authored-by: Yuri Shkuro <github@ysh.us>
  • Loading branch information
3 people committed Nov 29, 2023
1 parent 85303aa commit 112e880
Showing 1 changed file with 23 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

import memoizeOne from 'memoize-one';
import * as _ from 'lodash';
import DRange from 'drange';
import { Trace, Span } from '../../../types/trace';
Expand All @@ -21,6 +22,27 @@ import colorGenerator from '../../../utils/color-generator';
const serviceName = 'Service Name';
const operationName = 'Operation Name';

function parentChildOfMap(allSpans: Span[]): Record<string, Span[]> {
const parentChildOfMap: Record<string, Span[]> = {};
allSpans.forEach(s => {
if (s.references) {
// Filter for CHILD_OF we don't want to calculate FOLLOWS_FROM (prod-cons)
const parentIDs = s.references.filter(r => r.refType === 'CHILD_OF').map(r => r.spanID);
parentIDs.forEach((pID: string) => {
parentChildOfMap[pID] = parentChildOfMap[pID] || [];
parentChildOfMap[pID].push(s);
});
}
});
return parentChildOfMap;
}

const memoizedParentChildOfMap = memoizeOne(parentChildOfMap);

function getChildOfSpans(parentID: string, allSpans: Span[]): Span[] {
return memoizedParentChildOfMap(allSpans)[parentID] || [];
}

function computeSelfTime(span: Span, allSpans: Span[]): number {
if (!span.hasChildren) return span.duration;
// We want to represent spans as half-open intervals like [startTime, startTime + duration).
Expand All @@ -33,13 +55,7 @@ function computeSelfTime(span: Span, allSpans: Span[]): number {
// To work around that, we multiply start/end times by 10 and subtract one from the end.
// So instead of [1-10] we get [10-99]. This makes the intervals work like half-open.
const spanRange = new DRange(10 * span.startTime, 10 * (span.startTime + span.duration) - 1);
// Only keep CHILD_OF spans. FOLLOWS_FROM spans do not block the parent.
const children = allSpans.filter(
each =>
span.childSpanIds.includes(each.spanID) &&
each.references[0].spanID === span.spanID &&
each.references[0].refType === 'CHILD_OF'
);
const children = getChildOfSpans(span.spanID, allSpans);
children.forEach(child => {
spanRange.subtract(10 * child.startTime, 10 * (child.startTime + child.duration) - 1);
});
Expand Down

0 comments on commit 112e880

Please sign in to comment.