mergeBuckets.tsx 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. import {
  2. JobTickData,
  3. MonitorBucketData,
  4. } from 'sentry/views/monitors/components/overviewTimeline/types';
  5. import {filterMonitorStatsBucketByEnv} from './filterMonitorStatsBucketByEnv';
  6. import {getAggregateStatus} from './getAggregateStatus';
  7. import {getAggregateStatusFromMultipleBuckets} from './getAggregateStatusFromMultipleBuckets';
  8. import {isEnvMappingEmpty} from './isEnvMappingEmpty';
  9. import {mergeEnvMappings} from './mergeEnvMappings';
  10. function generateJobTickFromBucket(
  11. bucket: MonitorBucketData[number],
  12. options?: Partial<JobTickData>
  13. ) {
  14. const [timestamp, envMapping] = bucket;
  15. return {
  16. endTs: timestamp,
  17. startTs: timestamp,
  18. width: 1,
  19. envMapping,
  20. roundedLeft: false,
  21. roundedRight: false,
  22. ...options,
  23. };
  24. }
  25. export function mergeBuckets(data: MonitorBucketData, environment: string) {
  26. const minTickWidth = 4;
  27. const jobTicks: JobTickData[] = [];
  28. data.reduce((currentJobTick, bucket, i) => {
  29. const filteredBucket = filterMonitorStatsBucketByEnv(bucket, environment);
  30. const [timestamp, envMapping] = filteredBucket;
  31. const envMappingEmpty = isEnvMappingEmpty(envMapping);
  32. if (!currentJobTick) {
  33. return envMappingEmpty
  34. ? currentJobTick
  35. : generateJobTickFromBucket(filteredBucket, {roundedLeft: true});
  36. }
  37. const bucketStatus = getAggregateStatus(envMapping);
  38. const currJobTickStatus = getAggregateStatus(currentJobTick.envMapping);
  39. // If the current bucket is empty and our job tick has reached a min width
  40. if (envMappingEmpty && currentJobTick.width >= minTickWidth) {
  41. // Then add our current tick to the running list of job ticks to render
  42. currentJobTick.roundedRight = true;
  43. jobTicks.push(currentJobTick);
  44. return null;
  45. }
  46. const nextTickAggregateStatus = getAggregateStatusFromMultipleBuckets(
  47. data.slice(i, i + minTickWidth).map(([_, envData]) => envData)
  48. );
  49. // If the next buckets have a different status from our current job tick
  50. if (
  51. bucketStatus !== currJobTickStatus &&
  52. nextTickAggregateStatus !== currJobTickStatus &&
  53. currentJobTick.width >= minTickWidth
  54. ) {
  55. // Then add our current tick to the running list of job ticks to render
  56. jobTicks.push(currentJobTick);
  57. return generateJobTickFromBucket(filteredBucket);
  58. }
  59. // Merge our current tick with the current bucket data
  60. currentJobTick = {
  61. ...currentJobTick,
  62. endTs: timestamp,
  63. envMapping: mergeEnvMappings(currentJobTick.envMapping, envMapping),
  64. width: currentJobTick.width + 1,
  65. };
  66. // Ensure we render the last tick
  67. if (i === data.length - 1) {
  68. currentJobTick.roundedRight = true;
  69. jobTicks.push(currentJobTick);
  70. }
  71. return currentJobTick;
  72. }, null as JobTickData | null);
  73. return jobTicks;
  74. }