adminQueue.tsx 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. import styled from '@emotion/styled';
  2. import Button from 'sentry/components/button';
  3. import ButtonBar from 'sentry/components/buttonBar';
  4. import {SelectField} from 'sentry/components/deprecatedforms';
  5. import InternalStatChart from 'sentry/components/internalStatChart';
  6. import {Panel, PanelBody, PanelHeader} from 'sentry/components/panels';
  7. import AsyncView from 'sentry/views/asyncView';
  8. const TIME_WINDOWS = ['1h', '1d', '1w'] as const;
  9. type TimeWindow = typeof TIME_WINDOWS[number];
  10. type State = AsyncView['state'] & {
  11. activeTask: string;
  12. resolution: string;
  13. since: number;
  14. taskList: string[];
  15. taskName: string;
  16. timeWindow: TimeWindow;
  17. };
  18. export default class AdminQueue extends AsyncView<{}, State> {
  19. getDefaultState() {
  20. return {
  21. ...super.getDefaultState(),
  22. timeWindow: '1w',
  23. since: new Date().getTime() / 1000 - 3600 * 24 * 7,
  24. resolution: '1h',
  25. taskName: null,
  26. };
  27. }
  28. getEndpoints(): ReturnType<AsyncView['getEndpoints']> {
  29. return [['taskList', '/internal/queue/tasks/']];
  30. }
  31. changeWindow(timeWindow: TimeWindow) {
  32. let seconds: number;
  33. if (timeWindow === '1h') {
  34. seconds = 3600;
  35. } else if (timeWindow === '1d') {
  36. seconds = 3600 * 24;
  37. } else if (timeWindow === '1w') {
  38. seconds = 3600 * 24 * 7;
  39. } else {
  40. throw new Error('Invalid time window');
  41. }
  42. this.setState({
  43. since: new Date().getTime() / 1000 - seconds,
  44. timeWindow,
  45. });
  46. }
  47. changeTask(value: string) {
  48. this.setState({activeTask: value});
  49. }
  50. renderBody() {
  51. const {activeTask, taskList} = this.state;
  52. return (
  53. <div>
  54. <Header>
  55. <h3>Queue Overview</h3>
  56. <ButtonBar merged active={this.state.timeWindow}>
  57. {TIME_WINDOWS.map(r => (
  58. <Button size="sm" barId={r} onClick={() => this.changeWindow(r)} key={r}>
  59. {r}
  60. </Button>
  61. ))}
  62. </ButtonBar>
  63. </Header>
  64. <Panel>
  65. <PanelHeader>Global Throughput</PanelHeader>
  66. <PanelBody withPadding>
  67. <InternalStatChart
  68. since={this.state.since}
  69. resolution={this.state.resolution}
  70. stat="jobs.all.started"
  71. label="jobs started"
  72. />
  73. </PanelBody>
  74. </Panel>
  75. <h3>Task Details</h3>
  76. <div>
  77. <div className="m-b-1">
  78. <label>Show details for task:</label>
  79. <SelectField
  80. name="task"
  81. onChange={value => this.changeTask(value as string)}
  82. value={activeTask}
  83. clearable
  84. options={taskList.map(t => ({
  85. value: t,
  86. label: t,
  87. }))}
  88. />
  89. </div>
  90. {activeTask ? (
  91. <div>
  92. <Panel key={`jobs.started.${activeTask}`}>
  93. <PanelHeader>
  94. Jobs Started <small>{activeTask}</small>
  95. </PanelHeader>
  96. <PanelBody withPadding>
  97. <InternalStatChart
  98. since={this.state.since}
  99. resolution={this.state.resolution}
  100. stat={`jobs.started.${activeTask}`}
  101. label="jobs"
  102. height={100}
  103. />
  104. </PanelBody>
  105. </Panel>
  106. <Panel key={`jobs.finished.${activeTask}`}>
  107. <PanelHeader>
  108. Jobs Finished <small>{activeTask}</small>
  109. </PanelHeader>
  110. <PanelBody withPadding>
  111. <InternalStatChart
  112. since={this.state.since}
  113. resolution={this.state.resolution}
  114. stat={`jobs.finished.${activeTask}`}
  115. label="jobs"
  116. height={100}
  117. />
  118. </PanelBody>
  119. </Panel>
  120. </div>
  121. ) : null}
  122. </div>
  123. </div>
  124. );
  125. }
  126. }
  127. const Header = styled('div')`
  128. display: flex;
  129. justify-content: space-between;
  130. align-items: center;
  131. `;