IF YOU WOULD LIKE TO GET AN ACCOUNT, please write an email to s dot adaszewski at gmail dot com. User accounts are meant only to report issues and/or generate pull requests. This is a purpose-specific Git hosting for ADARED projects. Thank you for your understanding!
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

135 行
5.3KB

  1. import { h, Component } from 'preact';
  2. import WBTable from 'wb-table';
  3. import makeArvadosRequest from 'make-arvados-request';
  4. import wbProcessStateName from 'wb-process-state-name';
  5. function getAll(makeRequest) {
  6. let prom = makeRequest(0);
  7. prom = prom.then(xhr => {
  8. const { items, limit, items_available } = xhr.response;
  9. let res = [].concat(items);
  10. let prom_1 = new Promise(accept => accept());
  11. for (let ofs = limit; ofs < items_available; ofs += limit) {
  12. prom_1 = prom_1.then(() => makeRequest(ofs));
  13. prom_1 = prom_1.then(xhr_1 => {
  14. res = res.concat(xhr_1.response.items);
  15. });
  16. }
  17. prom_1 = prom_1.then(() => res);
  18. return prom_1;
  19. });
  20. return prom;
  21. }
  22. class WBProcessDashboard extends Component {
  23. constructor(...args) {
  24. super(...args);
  25. this.state.rows = Array(5).fill(Array(6).fill('-'));
  26. }
  27. fetchData() {
  28. const { app, parentProcessUuid } = this.props;
  29. const { arvHost, arvToken } = app.state;
  30. let prom = new Promise(accept => accept());
  31. if (parentProcessUuid) {
  32. prom = prom.then(() => {
  33. return makeArvadosRequest(arvHost, arvToken,
  34. '/arvados/v1/container_requests/' + encodeURIComponent(parentProcessUuid));
  35. });
  36. prom = prom.then(xhr => {
  37. const cr = xhr.response;
  38. if (!cr.container_uuid)
  39. return [];
  40. const filters = [ [ 'requesting_container_uuid', '=', cr.container_uuid ] ];
  41. return getAll(ofs =>
  42. makeArvadosRequest(arvHost, arvToken,
  43. '/arvados/v1/container_requests?filters=' +
  44. encodeURIComponent(JSON.stringify(filters)) +
  45. '&order=' + encodeURIComponent(JSON.stringify(['uuid asc'])) +
  46. '&offset=' + ofs));
  47. });
  48. } else {
  49. prom = prom.then(() => {
  50. return getAll(ofs => makeArvadosRequest(arvHost, arvToken,
  51. '/arvados/v1/container_requests?order=' +
  52. encodeURIComponent(JSON.stringify(['uuid asc'])) + '&offset=' + ofs));
  53. });
  54. }
  55. let crlist;
  56. prom = prom.then(crl => {
  57. crlist = crl;
  58. const uuids = crlist.map(a => a.container_uuid);
  59. // uuids = uuids.slice(0, 2);
  60. // crlist.map(a => ( crdict[a.uuid] = a));
  61. const filters = [ [ 'uuid', 'in', uuids ] ];
  62. return getAll(ofs => makeArvadosRequest(arvHost, arvToken,
  63. '/arvados/v1/containers?filters=' + encodeURIComponent(JSON.stringify(filters)) +
  64. '&order=' + encodeURIComponent(JSON.stringify([ 'uuid asc' ])) +
  65. '&offset=' + ofs));
  66. });
  67. prom = prom.then(cl => {
  68. cl.map(a => (crlist.find(b => (b.container_uuid === a.uuid)).container = a));
  69. crlist.map(a => (a.wb_state = wbProcessStateName(a, a.container)));
  70. const stats = {};
  71. for (let state in { 'Pending': 1, 'Running': 1, 'Complete': 1, 'Failed': 1, 'Cancelled': 1 }) {
  72. const f = crlist.filter(a => (a.wb_state === state));
  73. stats[state] = { 'Count': f.length };
  74. if (state === 'Pending')
  75. f.map(a => (a.wb_wait_time = (new Date() - new Date(a.created_at)) / 3.6e6));
  76. else
  77. f.map(a => (a.wb_wait_time = Math.max(0, (a.container ? new Date(a.container.started_at) : new Date(0)) - new Date(a.created_at)) / 3.6e6));
  78. f.sort((a, b) => (a.wb_wait_time - b.wb_wait_time));
  79. stats[state]['Shortest Wait Time'] = f.length ? (f[0].wb_wait_time.toFixed(2) + ' hours') : '-';
  80. stats[state]['Longest Wait Time'] = f.length ? (f[f.length - 1].wb_wait_time.toFixed(2) + ' hours') : '-';
  81. if (state === 'Pending')
  82. f.map(a => (a.wb_run_time = 0));
  83. else if (state === 'Running')
  84. f.map(a => (a.wb_run_time = (new Date() - new Date(a.container.started_at)) / 3.6e6));
  85. else
  86. f.map(a => (a.wb_run_time = Math.max(0, a.container ? new Date(a.container.finished_at) - new Date(a.container.started_at) : 0) / 3.6e6));
  87. f.sort((a, b) => (a.wb_run_time - b.wb_run_time));
  88. stats[state]['Shortest Run Time'] = f.length ? (f[0].wb_run_time.toFixed(2) + ' hours') : '-';
  89. stats[state]['Longest Run Time'] = f.length ? (f[f.length - 1].wb_run_time.toFixed(2) + ' hours') : '-';
  90. }
  91. const rows = [];
  92. for (let st in { 'Count': 1, 'Shortest Wait Time': 1, 'Longest Wait Time': 1,
  93. 'Shortest Run Time': 1, 'Longest Run Time': 1}) {
  94. rows.push([st].concat(['Pending', 'Running', 'Complete', 'Failed', 'Cancelled'].map(a => stats[a][st])));
  95. }
  96. this.setState({ rows });
  97. });
  98. }
  99. componentDidMount() {
  100. if (!this.props.lazy)
  101. this.fetchData();
  102. }
  103. componentWillReceiveProps(nextProps) {
  104. if (nextProps.parentProcessUuid === this.props.parentProcessUuid)
  105. return;
  106. if (this.props.lazy) {
  107. this.setState({ rows: Array(5).fill(Array(6).fill('-')) });
  108. return;
  109. }
  110. this.props = nextProps;
  111. this.fetchData();
  112. }
  113. render({ lazy }, { rows }) {
  114. return (
  115. <div>
  116. <WBTable columns={ [ 'State', 'Pending', 'Running', 'Complete', 'Failed', 'Cancelled' ] }
  117. rows={ rows } verticalHeader={ true } />
  118. { lazy ? (
  119. <a href="#" onclick={ e => { e.preventDefault(); this.fetchData(); } }>Refresh</a>
  120. ) : null }
  121. </div>
  122. );
  123. }
  124. }
  125. export default WBProcessDashboard;