From 17fb685941286331f1433ccf1cedf6224f673d2b Mon Sep 17 00:00:00 2001 From: Stanislaw Adaszewski Date: Fri, 21 Feb 2020 09:23:40 +0100 Subject: [PATCH] Made WBProcessListing more responsive. --- .../src/js/component/wb-process-listing.js | 83 +++---------------- frontend/src/js/component/wb-process-state.js | 47 +++++++++++ frontend/src/js/misc/wb-fetch-objects.js | 5 ++ frontend/src/js/page/wb-browse.js | 3 +- frontend/src/js/page/wb-process-view.js | 21 +++-- 5 files changed, 80 insertions(+), 79 deletions(-) create mode 100644 frontend/src/js/component/wb-process-state.js diff --git a/frontend/src/js/component/wb-process-listing.js b/frontend/src/js/component/wb-process-listing.js index 4dd69b0..fb95c94 100644 --- a/frontend/src/js/component/wb-process-listing.js +++ b/frontend/src/js/component/wb-process-listing.js @@ -7,6 +7,11 @@ import WBCheckboxes from 'wb-checkboxes'; import wbFormatDate from 'wb-format-date'; import wbFetchObjects from 'wb-fetch-objects'; import WBNameAndUuid from 'wb-name-and-uuid'; +import WBProcessState from 'wb-process-state'; + +function maskRows(rows) { + return rows.map(r => r.map(c => '-')); +} class WBProcessListing extends Component { @@ -15,9 +20,7 @@ class WBProcessListing extends Component { this.state.rows = []; this.state.numPages = 0; this.state.requestStates = [ 'Uncommitted', 'Committed', 'Final' ]; - // this.state.containerStates = [ 'Queued', 'Locked', 'Running', 'Cancelled', 'Complete' ]; this.state.reqStateMask = [ true, true, true ]; - // this.state.contStateMask = [ true, true, true, true, true ]; } componentDidMount() { @@ -25,14 +28,8 @@ class WBProcessListing extends Component { } prepareRows(requests, containerLookup, ownerLookup, outputLookup) { - const { renderRenameLink, renderDeleteButton } = this.props; + const { app, renderRenameLink, renderDeleteButton } = this.props; return requests.map(item => { - const container = item.container_uuid in containerLookup ? - containerLookup[item.container_uuid] : null; - const runtimeStatus = container ? container.runtime_status : null; - const error = runtimeStatus ? runtimeStatus.error : null; - const warning = runtimeStatus ? runtimeStatus.warning : null; - return ( [ (
@@ -42,22 +39,10 @@ class WBProcessListing extends Component {
{ item['uuid'] }
), - (
- { item['state'] } - { item.container_uuid ? - container ? - [ " / ", container.state ] : - [ " / ", Container Not Found ] : - null } - { !(error || warning) && container && container.state === 'Complete' ? " / Success" : null } - { error ? [" / ", E ] : null } - { warning ? [ " / ", W ] : null } -
), - ( ), + ( ), + ( ), wbFormatDate(item['created_at']), - ( ), + ( ), (
{ renderDeleteButton(item, () => this.fetchItems()) }
) @@ -78,64 +63,22 @@ class WBProcessListing extends Component { filters.push([ 'state', 'in', requestStates.filter((_, idx) => reqStateMask[idx]) ]); if (ownerUuid) filters.push([ 'owner_uuid', '=', ownerUuid ]); - //if (requestingContainerUuid) - //filters.push(); let prom = makeArvadosRequest(arvHost, arvToken, '/arvados/v1/container_requests?filters=' + encodeURIComponent(JSON.stringify(filters)) + '&limit=' + itemsPerPage + '&offset=' + (itemsPerPage * activePage)); - let requests; - let numPages; - prom = prom.then(xhr => { - requests = xhr.response.items; - numPages = Math.ceil(xhr.response['items_available'] / xhr.response['limit']); - /* container_uuids = requests.map(r => r.container_uuid); - container_uuids = container_uuids.filter(uuid => uuid); - const filters_1 = [ - [ 'uuid', 'in', container_uuids ] - ]; - return makeArvadosRequest(arvHost, arvToken, - '/arvados/v1/containers?filters=' + - encodeURIComponent(JSON.stringify(filters_1)));*/ - return wbFetchObjects(arvHost, arvToken, - requests.map(r => r.container_uuid).filter(uuid => uuid)); - }); - - let containerLookup; - prom = prom.then(lookup => { - containerLookup = lookup; - // const containers = xhr.response.items; - // containers.map(c => (containerLookup[c.uuid] = c)); - return wbFetchObjects(arvHost, arvToken, - requests.map(r => r.owner_uuid).filter(uuid => uuid)); - }); - - let ownerLookup; - prom = prom.then(lookup => { - ownerLookup = lookup; - return wbFetchObjects(arvHost, arvToken, - requests.map(r => r.output_uuid).filter(uuid => uuid)); - }); - - let outputLookup; - prom = prom.then(lookup => (outputLookup = lookup)); - - // prom = prom.then(() => makeArvadosRequest(arvHost, arvToken, - // '/arvados/v1/')) - - prom = prom.then(() => + prom = prom.then(xhr => this.setState({ - 'numPages': numPages, - 'rows': this.prepareRows(requests, containerLookup, - ownerLookup, outputLookup) + 'numPages': Math.ceil(xhr.response['items_available'] / xhr.response['limit']), + 'rows': this.prepareRows(xhr.response.items) })); } componentWillReceiveProps(nextProps, nextState) { - // this.setState({ 'rows': [] }); // .rows = []; this.props = nextProps; + this.setState({ 'rows': maskRows(this.state.rows) }); this.fetchItems(); } diff --git a/frontend/src/js/component/wb-process-state.js b/frontend/src/js/component/wb-process-state.js new file mode 100644 index 0000000..27387e0 --- /dev/null +++ b/frontend/src/js/component/wb-process-state.js @@ -0,0 +1,47 @@ +import { h, Component } from 'preact'; +import makeArvadosRequest from 'make-arvados-request'; + +class WBProcessState extends Component { + componentDidMount() { + this.fetchData(); + } + + componentWillReceiveProps(nextProps) { + this.props = nextProps; + this.fetchData(); + } + + fetchData() { + const { app, process } = this.props; + const { arvHost, arvToken } = app.state; + + if (!process.container_uuid) + return; + + let prom = makeArvadosRequest(arvHost, arvToken, + '/arvados/v1/containers/' + process.container_uuid); + prom = prom.then(xhr => this.setState({ 'container': xhr.response })); + prom = prom.catch(() => this.setState({ 'apiError': 'Failed to fetch container' })); + } + + render({ process }, { container, apiError }) { + const runtimeStatus = container ? container.runtime_status : null; + const error = runtimeStatus ? runtimeStatus.error : null; + const warning = runtimeStatus ? runtimeStatus.warning : null; + + return ( +
+ { process.state } + { apiError ? { [ ' / ', apiError ] } : null } + { container ? [ " / ", container.state ] : null } + { !(error || warning) && container && container.state === 'Complete' ? " / Success" : null } + { error ? [" / ", E ] : null } + { warning ? [ " / ", W ] : null } +
+ ); + } +} + +export default WBProcessState; diff --git a/frontend/src/js/misc/wb-fetch-objects.js b/frontend/src/js/misc/wb-fetch-objects.js index bcc47e2..64e5a5a 100644 --- a/frontend/src/js/misc/wb-fetch-objects.js +++ b/frontend/src/js/misc/wb-fetch-objects.js @@ -7,6 +7,10 @@ function wbFetchObjects(arvHost, arvToken, uuids) { uuids = {}; Object.keys(unique).map(u => { let typeName = arvadosTypeName(u); + if (!typeName) { + console.log('Unknown type name for UUID: ' + u); + return; + } if (!(typeName in uuids)) uuids[typeName] = []; uuids[typeName].push(u); @@ -23,6 +27,7 @@ function wbFetchObjects(arvHost, arvToken, uuids) { encodeURIComponent(JSON.stringify(filters)))); prom = prom.then(xhr => xhr.response.items.map(it => ( lookup[it.uuid] = it))); + prom = prom.catch(xhr => console.log(xhr.responseURL + ': ' + xhr.statusText)); } prom = prom.then(() => lookup); diff --git a/frontend/src/js/page/wb-browse.js b/frontend/src/js/page/wb-browse.js index b4ea93d..91490f2 100644 --- a/frontend/src/js/page/wb-browse.js +++ b/frontend/src/js/page/wb-browse.js @@ -121,7 +121,8 @@ class WBBrowse extends Component { renderDeleteButton={ (it, cb) => this.renderDeleteButton(it, cb) } /> ) : (objTypeTab === 'process') ? ( - (dict[u] = true)); return Object.keys(dict); }); - prom = prom.then(uuids => { + prom = prom.then(uuids => wbFetchObjects(arvHost, arvToken, uuids)); + /* prom = prom.then(() => { // let uuids = detectUuids([ req, cont ]); - let objectTypes = uuids.map(u => arvadosTypeName(u.split('-')[1]) + 's'); + let objectTypes = uuids.map(u => arvadosTypeName(u) + 's'); + //objectTypes = objectTypes.filter(ot => ot); + //objectTypes = objectTypes.map(ot => ot + 's'); let objQueries = {}; objectTypes.map(t => (objQueries[t] = [])); uuids.map((u, idx) => (objQueries[objectTypes[idx]].push(u))); @@ -76,11 +80,11 @@ class WBProcessView extends Component { } prom_1 = prom_1.then(() => objects); return prom_1; - }); + }); */ prom = prom.then(objects => { - let objDict = {}; - objects.map(o => (objDict[o['uuid']] = o)); - let urls = objects.map(o => urlForObject(o)); + // let objDict = {}; + // objects.map(o => (objDict[o['uuid']] = o)); + let urls = Object.values(objects).map(o => urlForObject(o)); this.setState({ 'objectUrls': urls, 'request': req, @@ -95,7 +99,7 @@ class WBProcessView extends Component { componentWillReceiveProps(nextProps) { this.props = nextProps; - this.setState({ 'objectUrls': [], 'request': null, 'container': null }); + // this.setState({ 'objectUrls': [], 'request': null, 'container': null }); this.fetchData(); } @@ -118,7 +122,8 @@ class WBProcessView extends Component { { container ? ([

Children

, -