|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150 |
- import { h, Component } from 'preact';
- import WBTable from 'wb-table';
- import makeArvadosRequest from 'make-arvados-request';
-
- function getAll(makeRequest) {
- let prom = makeRequest(0);
- prom = prom.then(xhr => {
- const { items, limit, items_available } = xhr.response;
- let res = [].concat(items);
- let prom_1 = new Promise(accept => accept());
- for (let ofs = limit; ofs < items_available; ofs += limit) {
- prom_1 = prom_1.then(() => makeRequest(ofs));
- prom_1 = prom_1.then(xhr_1 => {
- res = res.concat(xhr_1.response.items);
- });
- }
- prom_1 = prom_1.then(() => res);
- return prom_1;
- });
- return prom;
- }
-
- function determineState(containerRequest) {
- const cr = containerRequest;
- const c = cr.container;
- if (cr.state !== 'Uncommitted' && cr.priority === 0)
- return 'Cancelled';
- if (cr.state === 'Uncommitted' || !c || c.state === 'Queued' || c.state === 'Locked')
- return 'Pending';
- if (c.state === 'Running')
- return 'Running';
- if (c.state === 'Complete' && c.exit_code === 0)
- return 'Complete';
- if (c.state === 'Complete' && c.exit_code !== 0)
- return 'Failed';
- if (c.state === 'Cancelled')
- return 'Cancelled';
- }
-
- class WBProcessDashboard extends Component {
- constructor(...args) {
- super(...args);
- this.state.rows = Array(5).fill(Array(6).fill('-'));
- }
-
- fetchData() {
- const { app, parentProcessUuid } = this.props;
- const { arvHost, arvToken } = app.state;
- let prom = new Promise(accept => accept());
- if (parentProcessUuid) {
- prom = prom.then(() => {
- return makeArvadosRequest(arvHost, arvToken,
- '/arvados/v1/container_requests/' + encodeURIComponent(parentProcessUuid));
- });
- prom = prom.then(xhr => {
- const cr = xhr.response;
- if (!cr.container_uuid)
- return [];
- const filters = [ [ 'requesting_container_uuid', '=', cr.container_uuid ] ];
- return getAll(ofs =>
- makeArvadosRequest(arvHost, arvToken,
- '/arvados/v1/container_requests?filters=' +
- encodeURIComponent(JSON.stringify(filters)) +
- '&order=' + encodeURIComponent(JSON.stringify(['uuid asc'])) +
- '&offset=' + ofs));
- });
- } else {
- prom = prom.then(() => {
- return getAll(ofs => makeArvadosRequest(arvHost, arvToken,
- '/arvados/v1/container_requests?order=' +
- encodeURIComponent(JSON.stringify(['uuid asc'])) + '&offset=' + ofs));
- });
- }
- let crlist;
- prom = prom.then(crl => {
- crlist = crl;
- const uuids = crlist.map(a => a.container_uuid);
- // uuids = uuids.slice(0, 2);
- // crlist.map(a => ( crdict[a.uuid] = a));
- const filters = [ [ 'uuid', 'in', uuids ] ];
- return getAll(ofs => makeArvadosRequest(arvHost, arvToken,
- '/arvados/v1/containers?filters=' + encodeURIComponent(JSON.stringify(filters)) +
- '&order=' + encodeURIComponent(JSON.stringify([ 'uuid asc' ])) +
- '&offset=' + ofs));
- });
- prom = prom.then(cl => {
- cl.map(a => (crlist.find(b => (b.container_uuid === a.uuid)).container = a));
- crlist.map(a => (a.wb_state = determineState(a)));
- const stats = {};
- for (let state in { 'Pending': 1, 'Running': 1, 'Complete': 1, 'Failed': 1, 'Cancelled': 1 }) {
- const f = crlist.filter(a => (a.wb_state === state));
- stats[state] = { 'Count': f.length };
- if (state === 'Pending')
- f.map(a => (a.wb_wait_time = (new Date() - new Date(a.created_at)) / 3.6e6));
- else
- 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));
- f.sort((a, b) => (a.wb_wait_time - b.wb_wait_time));
- stats[state]['Shortest Wait Time'] = f.length ? (f[0].wb_wait_time.toFixed(2) + ' hours') : '-';
- stats[state]['Longest Wait Time'] = f.length ? (f[f.length - 1].wb_wait_time.toFixed(2) + ' hours') : '-';
- if (state === 'Pending')
- f.map(a => (a.wb_run_time = 0));
- else if (state === 'Running')
- f.map(a => (a.wb_run_time = (new Date() - new Date(a.container.started_at)) / 3.6e6));
- else
- 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));
- f.sort((a, b) => (a.wb_run_time - b.wb_run_time));
- stats[state]['Shortest Run Time'] = f.length ? (f[0].wb_run_time.toFixed(2) + ' hours') : '-';
- stats[state]['Longest Run Time'] = f.length ? (f[f.length - 1].wb_run_time.toFixed(2) + ' hours') : '-';
- }
- const rows = [];
- for (let st in { 'Count': 1, 'Shortest Wait Time': 1, 'Longest Wait Time': 1,
- 'Shortest Run Time': 1, 'Longest Run Time': 1}) {
- rows.push([st].concat(['Pending', 'Running', 'Complete', 'Failed', 'Cancelled'].map(a => stats[a][st])));
- }
- this.setState({ rows });
- });
- }
-
- componentDidMount() {
- if (!this.props.lazy)
- this.fetchData();
- }
-
- componentWillReceiveProps(nextProps) {
- if (nextProps.parentProcessUuid === this.props.parentProcessUuid)
- return;
-
- if (this.props.lazy) {
- this.setState({ rows: Array(5).fill(Array(6).fill('-')) });
- return;
- }
-
- this.props = nextProps;
- this.fetchData();
- }
-
- render({ lazy }, { rows }) {
- return (
- <div>
- <WBTable columns={ [ 'State', 'Pending', 'Running', 'Complete', 'Failed', 'Cancelled' ] }
- rows={ rows } verticalHeader={ true } />
- { lazy ? (
- <a href="#" onclick={ e => { e.preventDefault(); this.fetchData(); } }>Refresh</a>
- ) : null }
- </div>
- );
- }
- }
-
- export default WBProcessDashboard;
|