mergeBuckets.tsx 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. import type {
  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(
  29. (currentJobTick, bucket, i) => {
  30. const filteredBucket = filterMonitorStatsBucketByEnv(bucket, environment);
  31. const [timestamp, envMapping] = filteredBucket;
  32. const envMappingEmpty = isEnvMappingEmpty(envMapping);
  33. if (!currentJobTick) {
  34. return envMappingEmpty
  35. ? currentJobTick
  36. : generateJobTickFromBucket(filteredBucket, {roundedLeft: true});
  37. }
  38. const bucketStatus = getAggregateStatus(envMapping);
  39. const currJobTickStatus = getAggregateStatus(currentJobTick.envMapping);
  40. // If the current bucket is empty and our job tick has reached a min width
  41. if (envMappingEmpty && currentJobTick.width >= minTickWidth) {
  42. // Then add our current tick to the running list of job ticks to render
  43. currentJobTick.roundedRight = true;
  44. jobTicks.push(currentJobTick);
  45. return null;
  46. }
  47. const nextTickAggregateStatus = getAggregateStatusFromMultipleBuckets(
  48. data.slice(i, i + minTickWidth).map(([_, envData]) => envData)
  49. );
  50. // If the next buckets have a different status from our current job tick
  51. if (
  52. bucketStatus !== currJobTickStatus &&
  53. nextTickAggregateStatus !== currJobTickStatus &&
  54. currentJobTick.width >= minTickWidth
  55. ) {
  56. // Then add our current tick to the running list of job ticks to render
  57. jobTicks.push(currentJobTick);
  58. return generateJobTickFromBucket(filteredBucket);
  59. }
  60. // Merge our current tick with the current bucket data
  61. currentJobTick = {
  62. ...currentJobTick,
  63. endTs: timestamp,
  64. envMapping: mergeEnvMappings(currentJobTick.envMapping, envMapping),
  65. width: currentJobTick.width + 1,
  66. };
  67. // Ensure we render the last tick
  68. if (i === data.length - 1) {
  69. currentJobTick.roundedRight = true;
  70. jobTicks.push(currentJobTick);
  71. }
  72. return currentJobTick;
  73. },
  74. null as JobTickData | null
  75. );
  76. return jobTicks;
  77. }