Skip to content

Commit

Permalink
ref(crons): new merge/aggregate status functions without `MonitorBuck…
Browse files Browse the repository at this point in the history
…etEnvMapping` (#82566)

introducing new functions to replace:
- `getAggregateStatus`
- `getAggregateStatusFromMultipleBuckets`
- `mergeEnvMappings`

since `checkinTimeline` doesn't need to know anything about environment,
we want to change these functions to take in `StatsBucket` instead of
`MonitorBucketEnvMapping` types

replacing usage + deleting old functions will come in following PRs
  • Loading branch information
ameliahsu authored Dec 26, 2024
1 parent 47142d4 commit c11f4c0
Show file tree
Hide file tree
Showing 6 changed files with 129 additions and 7 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import {CheckInStatus} from 'sentry/views/monitors/types';

import {getAggregateStatus} from './getAggregateStatus';
import {
getAggregateStatus,
getAggregateStatusFromStatsBucket,
} from './getAggregateStatus';

type StatusCounts = [
in_progress: number,
Expand All @@ -18,6 +21,18 @@ export function generateEnvMapping(name: string, counts: StatusCounts) {
};
}

export function generateStats(counts: StatusCounts) {
const [in_progress, ok, missed, timeout, error, unknown] = counts;
return {
in_progress,
ok,
missed,
timeout,
error,
unknown,
};
}

describe('getAggregateStatus', function () {
it('aggregates correctly across multiple envs', function () {
const envData = {
Expand All @@ -27,3 +42,10 @@ describe('getAggregateStatus', function () {
expect(getAggregateStatus(envData)).toEqual(CheckInStatus.ERROR);
});
});

describe('getAggregateStatusFromStatsBucket', function () {
it('aggregates correctly', function () {
const stats = generateStats([0, 1, 2, 0, 1, 0]);
expect(getAggregateStatusFromStatsBucket(stats)).toEqual(CheckInStatus.ERROR);
});
});
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type {MonitorBucketEnvMapping} from '../types';
import type {MonitorBucketEnvMapping, StatsBucket} from '../types';

import {CHECKIN_STATUS_PRECEDENT} from './constants';

Expand All @@ -12,3 +12,10 @@ export function getAggregateStatus(envData: MonitorBucketEnvMapping) {
return currentStatus;
}, CHECKIN_STATUS_PRECEDENT[0]);
}

export function getAggregateStatusFromStatsBucket(stats: StatsBucket) {
return (
[...CHECKIN_STATUS_PRECEDENT].reverse().find(status => stats[status] > 0) ||
CHECKIN_STATUS_PRECEDENT[0]
);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import {CheckInStatus} from 'sentry/views/monitors/types';

import {getAggregateStatusFromMultipleBuckets} from './getAggregateStatusFromMultipleBuckets';
import {
getAggregateStatusFromMultipleBuckets,
getAggregateStatusFromMultipleStatsBuckets,
} from './getAggregateStatusFromMultipleBuckets';

type StatusCounts = [
in_progress: number,
Expand All @@ -18,6 +21,18 @@ export function generateEnvMapping(name: string, counts: StatusCounts) {
};
}

export function generateStats(counts: StatusCounts) {
const [in_progress, ok, missed, timeout, error, unknown] = counts;
return {
in_progress,
ok,
missed,
timeout,
error,
unknown,
};
}

describe('getAggregateStatusFromMultipleBuckets', function () {
it('aggregates correctly across multiple envs', function () {
const envData1 = generateEnvMapping('prod', [2, 1, 2, 1, 0, 0]);
Expand All @@ -29,3 +44,15 @@ describe('getAggregateStatusFromMultipleBuckets', function () {
expect(status).toEqual(CheckInStatus.TIMEOUT);
});
});

describe('getAggregateStatusFromMultipleStatsBuckets', function () {
it('aggregates correctly across multiple envs', function () {
const stats1 = generateStats([2, 1, 2, 1, 0, 0]);
const stats2 = generateStats([1, 2, 0, 0, 0, 0]);
const stats3 = generateStats([1, 1, 1, 3, 0, 0]);

const status = getAggregateStatusFromMultipleStatsBuckets([stats1, stats2, stats3]);

expect(status).toEqual(CheckInStatus.TIMEOUT);
});
});
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import type {MonitorBucketEnvMapping} from '../types';
import type {MonitorBucketEnvMapping, StatsBucket} from '../types';

import {CHECKIN_STATUS_PRECEDENT} from './constants';
import {getAggregateStatus} from './getAggregateStatus';
import {
getAggregateStatus,
getAggregateStatusFromStatsBucket,
} from './getAggregateStatus';

/**
* Given multiple env buckets [{prod: {ok: 1, ...}, {prod: {ok: 0, ...}}]
Expand All @@ -21,3 +24,20 @@ export function getAggregateStatusFromMultipleBuckets(
CHECKIN_STATUS_PRECEDENT[0]
);
}

/**
* Given multiple stats buckets [{..., error: 1, unknown: 0}, {..., error: 0, unknown: 4}]
* returns the aggregate status across all buckets (unknown)
*/
export function getAggregateStatusFromMultipleStatsBuckets(statsArr: StatsBucket[]) {
return statsArr
.map(getAggregateStatusFromStatsBucket)
.reduce(
(aggregateStatus, currentStatus) =>
CHECKIN_STATUS_PRECEDENT.indexOf(currentStatus) >
CHECKIN_STATUS_PRECEDENT.indexOf(aggregateStatus)
? currentStatus
: aggregateStatus,
CHECKIN_STATUS_PRECEDENT[0]
);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,30 @@
import type {MonitorBucketEnvMapping} from 'sentry/views/monitors/components/timeline/types';
import type {
MonitorBucketEnvMapping,
StatsBucket,
} from 'sentry/views/monitors/components/timeline/types';

import {mergeEnvMappings} from './mergeEnvMappings';
import {mergeEnvMappings, mergeStats} from './mergeEnvMappings';

type StatusCounts = [
in_progress: number,
ok: number,
missed: number,
timeout: number,
error: number,
unknown: number,
];

export function generateStats(counts: StatusCounts) {
const [in_progress, ok, missed, timeout, error, unknown] = counts;
return {
in_progress,
ok,
missed,
timeout,
error,
unknown,
};
}

describe('mergeEnvMappings', function () {
it('merges two empty mappings', function () {
Expand Down Expand Up @@ -52,3 +76,14 @@ describe('mergeEnvMappings', function () {
expect(mergedMapping).toEqual(expectedMerged);
});
});

describe('mergeStats', function () {
it('merges two filled mappings', function () {
const statsA: StatsBucket = generateStats([0, 0, 1, 2, 1, 0]);
const statsB: StatsBucket = generateStats([2, 1, 1, 0, 2, 0]);
const expectedMerged: StatsBucket = generateStats([2, 1, 2, 2, 3, 0]);
const mergedStats = mergeStats(statsA, statsB);

expect(mergedStats).toEqual(expectedMerged);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,14 @@ export function mergeEnvMappings(
return mergedEnvs;
}, {});
}

/**
* Combines job status counts
*/
export function mergeStats(statsA: StatsBucket, statsB: StatsBucket): StatsBucket {
const combinedStats = {} as StatsBucket;
for (const status of CHECKIN_STATUS_PRECEDENT) {
combinedStats[status] = (statsA[status] ?? 0) + (statsB[status] ?? 0);
}
return combinedStats;
}

0 comments on commit c11f4c0

Please sign in to comment.