diff --git a/frontend/src/js/component/wb-process-dashboard.js b/frontend/src/js/component/wb-process-dashboard.js
index 561fa02..bc02f24 100644
--- a/frontend/src/js/component/wb-process-dashboard.js
+++ b/frontend/src/js/component/wb-process-dashboard.js
@@ -1,4 +1,5 @@
import { h, Component } from 'preact';
+import WBTable from 'wb-table';
import makeArvadosRequest from 'make-arvados-request';
function getAll(makeRequest) {
@@ -19,38 +20,114 @@ function getAll(makeRequest) {
return prom;
}
+function determineState(containerRequest) {
+ const cr = containerRequest;
+ const c = cr.container;
+ 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, uuid } = this.props;
+ const { app, parentProcessUuid } = this.props;
const { arvHost, arvToken } = app.state;
let prom = new Promise(accept => accept());
- if (uuid) {
+ if (parentProcessUuid) {
prom = prom.then(() => {
return makeArvadosRequest(arvHost, arvToken,
- '/arvados/v1/container_requests/' + encodeURIComponent(uuid));
+ '/arvados/v1/container_requests/' + encodeURIComponent(parentProcessUuid));
});
prom = prom.then(xhr => {
const cr = xhr.response;
- return makeArvadosRequest(arvHost, arvToken,
- '/arvados/v1/containers/' + encodeURIComponent(cr.container_uuid));
- });
- prom = prom.then(xhr => {
- const c = xhr.response;
- const filters = [ [ 'requesting_container_uuid', '=', c.uuid ] ];
- return makeArvadosRequest(arvHost, arvToken,
- '/arvados/v1/container_requests?filters=' +
- encodeURIComponent(JSON.stringify(filters)));
+ 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(['uuid asc']) +
+ '&offset=' + ofs));
});
} else {
prom = prom.then(() => {
- return makeArvadosRequest(arvHost, arvToken,
- '/arvados/v1/container_requests');
+ return getAll(ofs => makeArvadosRequest(arvHost, arvToken,
+ '/arvados/v1/container_requests?order=' +
+ encodeURIComponent(['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)) +
+ '&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 = (new Date(a.container.started_at) - 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, new Date(a.container.finished_at) - new Date(a.container.started_at)) / 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() {
+ this.fetchData();
}
- render() {
+ /* componentWillReceiveProps(nextProps) {
+ this.props = nextProps;
+ fetchData();
+ } */
+ render({}, { rows }) {
+ return (
+