Loading vospace-ui-backend/src/main/java/it/inaf/ia2/vospace/ui/service/NodeInfo.java +2 −2 Original line number Diff line number Diff line Loading @@ -48,8 +48,8 @@ public class NodeInfo { this.sticky = isSticky(node); this.busy = isBusy(node); this.listOfFiles = isListOfFiles(node); this.writable = NodeUtils.checkIfWritable(node, user.getName(), user.getGroups()); this.deletable = writable && !sticky; this.writable = NodeUtils.checkIfWritable(node, user.getName(), user.getGroups()) && !busy; this.deletable = writable && !sticky && !asyncTrans; } private String getPath(Node node) { Loading vospace-ui-frontend/src/App.vue +9 −1 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import { mapState } from 'vuex' import TopMenu from './components/TopMenu.vue' import client from 'api-client' import nodesReloader from './nodesReloader.js' export default { name: 'App', Loading @@ -34,6 +35,13 @@ export default { this.$store.dispatch('loadJobs'); this.$store.dispatch('loadUserInfo'); setInterval(client.keepalive, 60000); setInterval(nodesReloader.checkNodes, 1000); let self = this; setInterval(function() { if (self.$router.currentRoute.path !== '/jobs') { self.$store.dispatch('checkJobs'); } }, 1000); } } </script> Loading vospace-ui-frontend/src/api/server/index.js +4 −4 Original line number Diff line number Diff line Loading @@ -46,7 +46,7 @@ function escapePath(path) { } export default { getNode(path) { getNode(path, loading) { let url = BASE_API_URL + 'nodes/' + escapePath(path); return apiRequest({ method: 'GET', Loading @@ -55,7 +55,7 @@ export default { headers: { 'Cache-Control': 'no-cache' } }, true, true); }, (typeof loading !== 'undefined') ? loading : true, true); }, loadJobs() { let url = BASE_API_URL + 'jobs'; Loading Loading @@ -124,11 +124,11 @@ export default { uploadFile(url, file) { let formData = new FormData(); formData.append('file', file); axios.put(url, formData, { return axios.put(url, formData, { headers: { 'Content-Type': 'multipart/form-data' } }) }); }, deleteNodes(paths) { let url = BASE_API_URL + 'delete'; Loading vospace-ui-frontend/src/components/Jobs.vue +1 −0 Original line number Diff line number Diff line <template> <div> <b-button variant="primary" class="float-right" @click="loadJobs">Reload</b-button> <h3>Async recall jobs</h3> <table class="table b-table table-striped table-hover"> <thead> Loading vospace-ui-frontend/src/nodesReloader.js 0 → 100644 +49 −0 Original line number Diff line number Diff line import store from './store.js' import client from 'api-client' let lastResultTime = null; let times = 0; function checkNodes() { let busyNodes = document.getElementsByClassName('node-busy').length > 0; let jobsInProgress = store.state.jobs.filter(j => j.phase === 'EXECUTING').length > 0; if (!busyNodes && !jobsInProgress) { // reset state lastResultTime = null; times = 0; return; } if (lastResultTime !== null) { // first 10 times check every second, then check every ten seconds let offset = times < 10 ? 1000 : 10000; let now = new Date().getTime(); if (now - lastResultTime < offset) { return; } } if (!store.state.nodesLoading) { let path = store.state.path; store.commit('setNodesLoading', true); client.getNode(path, false) .then(res => { // check that path didn't change in meantime by user action if (path === store.state.path) { let resHasBusyNodes = res.htmlTable.includes('node-busy'); if ((!busyNodes && resHasBusyNodes) || (busyNodes && !resHasBusyNodes)) { store.dispatch('setNodes', res); } else { times++; lastResultTime = new Date().getTime(); } } }) .finally(() => { store.commit('setNodesLoading', false); }); } } export default { checkNodes } Loading
vospace-ui-backend/src/main/java/it/inaf/ia2/vospace/ui/service/NodeInfo.java +2 −2 Original line number Diff line number Diff line Loading @@ -48,8 +48,8 @@ public class NodeInfo { this.sticky = isSticky(node); this.busy = isBusy(node); this.listOfFiles = isListOfFiles(node); this.writable = NodeUtils.checkIfWritable(node, user.getName(), user.getGroups()); this.deletable = writable && !sticky; this.writable = NodeUtils.checkIfWritable(node, user.getName(), user.getGroups()) && !busy; this.deletable = writable && !sticky && !asyncTrans; } private String getPath(Node node) { Loading
vospace-ui-frontend/src/App.vue +9 −1 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import { mapState } from 'vuex' import TopMenu from './components/TopMenu.vue' import client from 'api-client' import nodesReloader from './nodesReloader.js' export default { name: 'App', Loading @@ -34,6 +35,13 @@ export default { this.$store.dispatch('loadJobs'); this.$store.dispatch('loadUserInfo'); setInterval(client.keepalive, 60000); setInterval(nodesReloader.checkNodes, 1000); let self = this; setInterval(function() { if (self.$router.currentRoute.path !== '/jobs') { self.$store.dispatch('checkJobs'); } }, 1000); } } </script> Loading
vospace-ui-frontend/src/api/server/index.js +4 −4 Original line number Diff line number Diff line Loading @@ -46,7 +46,7 @@ function escapePath(path) { } export default { getNode(path) { getNode(path, loading) { let url = BASE_API_URL + 'nodes/' + escapePath(path); return apiRequest({ method: 'GET', Loading @@ -55,7 +55,7 @@ export default { headers: { 'Cache-Control': 'no-cache' } }, true, true); }, (typeof loading !== 'undefined') ? loading : true, true); }, loadJobs() { let url = BASE_API_URL + 'jobs'; Loading Loading @@ -124,11 +124,11 @@ export default { uploadFile(url, file) { let formData = new FormData(); formData.append('file', file); axios.put(url, formData, { return axios.put(url, formData, { headers: { 'Content-Type': 'multipart/form-data' } }) }); }, deleteNodes(paths) { let url = BASE_API_URL + 'delete'; Loading
vospace-ui-frontend/src/components/Jobs.vue +1 −0 Original line number Diff line number Diff line <template> <div> <b-button variant="primary" class="float-right" @click="loadJobs">Reload</b-button> <h3>Async recall jobs</h3> <table class="table b-table table-striped table-hover"> <thead> Loading
vospace-ui-frontend/src/nodesReloader.js 0 → 100644 +49 −0 Original line number Diff line number Diff line import store from './store.js' import client from 'api-client' let lastResultTime = null; let times = 0; function checkNodes() { let busyNodes = document.getElementsByClassName('node-busy').length > 0; let jobsInProgress = store.state.jobs.filter(j => j.phase === 'EXECUTING').length > 0; if (!busyNodes && !jobsInProgress) { // reset state lastResultTime = null; times = 0; return; } if (lastResultTime !== null) { // first 10 times check every second, then check every ten seconds let offset = times < 10 ? 1000 : 10000; let now = new Date().getTime(); if (now - lastResultTime < offset) { return; } } if (!store.state.nodesLoading) { let path = store.state.path; store.commit('setNodesLoading', true); client.getNode(path, false) .then(res => { // check that path didn't change in meantime by user action if (path === store.state.path) { let resHasBusyNodes = res.htmlTable.includes('node-busy'); if ((!busyNodes && resHasBusyNodes) || (busyNodes && !resHasBusyNodes)) { store.dispatch('setNodes', res); } else { times++; lastResultTime = new Date().getTime(); } } }) .finally(() => { store.commit('setNodesLoading', false); }); } } export default { checkNodes }