/** * Project : AMDA-NG4 * Name : BkgJobNode.js * @class amdaModel.BkgJobNode * @extends amdaModel.AmdaNode * @brief Basic Model of Node corresponding to Amda processes in background * @author elena * @version $Id: BkgJobNode.js 1963 2013-12-06 17:50:37Z elena $ */ Ext.define('amdaModel.BkgJobNode', { extend: 'amdaModel.ExecutableNode', requires: [ 'amdaPlotObj.PlotRequestObject' ], action : null, statics: { nodeType: 'bkgWorks', JOB_TYPES: { PLOT: 'request',//'plot', CONDITION: 'condition', DOWNLOAD: 'download', STATISTICS: 'statistics' }, JOB_ROOT_NODE: { PLOT: 'bkgPlot-treeRootNode', CONDITION: 'bkgSearch-treeRootNode', DOWNLOAD: 'bkgDown-treeRootNode', STATISTICS: 'bkgStatistics-treeRootNode' }, RES_ROOT_NODE: { PLOT: 'resPlot-treeRootNode', CONDITION: 'resSearch-treeRootNode', DOWNLOAD: 'resDown-treeRootNode', STATISTICS: 'resStatistics-treeRootNode' }, STATUS_LIST: { IN_PROGRESS: 'in_progress', DONE: 'done', ERROR: 'error' } }, fields: [ // name, id, moduleId, object > from parent { name : 'jobType', type : 'string' }, { name : 'processId', type : 'string' }, { name : 'status', type : 'string' }, { name : 'percentDone', type : 'string', defaultValue : '0' }, { name : 'start', type: 'date' }, // { name : 'duration', type: 'int' , defaultValue: -1} { name : 'stop', type: 'date', defaultValue: null }, { name : 'rawname', type: 'string'}, { name : 'tabId', type: 'string'}, { name : 'info', type: 'string'} ], constructor : function(config) { this.callParent(arguments); this.set('ownerTreeId', amdaUI.ExplorerUI.JOB_TAB.TREE_ID); if (this.isLeaf()) { switch (this.get('status')) { case amdaModel.BkgJobNode.STATUS_LIST.ERROR: // this.set('status' ,amdaModel.BkgJobNode.STATUS_LIST.ERROR); this.set('iconCls','icon-error'); break; case amdaModel.BkgJobNode.STATUS_LIST.DONE: // set status // this.set('status',amdaModel.BkgJobNode.STATUS_LIST.DONE); this.set('iconCls','icon-done'); break; default : this.set('percentDone',this.get('status')); this.set('status',amdaModel.BkgJobNode.STATUS_LIST.IN_PROGRESS); this.set('iconCls','icon-pend'); } if (!this.get('processId') && this.get('id')) this.set('processId', this.get('id')); if (config) this.set('jobType', config.jobType); else this.set('jobType',this.get('jobType')); } }, getAllContextMenuItems: function() { if (this.get('status') == amdaModel.BkgJobNode.STATUS_LIST.IN_PROGRESS) return [ { fnId : 'leaf-deleteNode', text : 'Stop/Delete Job' }/*, { fnId : 'leaf-showNode', text : 'Show Job Details' }, { fnId : 'leaf-renameNode', text : 'Rename Job' }*/]; else return [{ fnId : 'leaf-editNode', text : 'Show Result' },{ fnId : 'leaf-deleteNode', text : 'Delete Result' }/*, { fnId : 'leaf-renameNode', text : 'Rename Result' }*/]; }, getMultiContextMenuItems: function() { return [{ fnId : 'mult-deleteMulti', text : 'Delete Results' }]; }, onMenuItemClick : function(menu, item, event) { var fnId = Ext.util.Format.substr(item.fnId, 5, item.fnId.length); switch (fnId) { case 'deleteNode': this.deleteJob(); this.deleteNode(); break; case 'showNode': //alert('Show details pid ' + this.get('pid')); alert('NOT IMPLEMENTED YET'); break; case 'renameNode': // alert('rename pid ' + this.get('pid')); alert('NOT IMPLEMENTED YET'); // this.renameNode(); break; case 'editNode': // create object if it doesn't exist (tree load) // TODO use data model ? if (!this.get('object')) { AmdaAction.getObject(this.get('id'), this.get('nodeType'), this.getObjectCallback, this); } else { var isInteractive = false; var isNewTab = true; this.editNode(isNewTab, isInteractive); } break; case 'deleteMulti': var selectedNodes = this.myGetOwnerTree().getSelectionModel().selected.items; if (selectedNodes.length > 0) { Ext.Array.each(selectedNodes,function(item, index){ item.deleteJob(); item.deleteNode(); }); } break; default: break; } }, deleteJob : function() { if (this.get('status') == amdaModel.BkgJobNode.STATUS_LIST.IN_PROGRESS) { amdaDesktop.JobsMgr.jobsInProgress--; if (amdaDesktop.JobsMgr.jobsInProgress == 0 && amdaDesktop.JobsMgr.updateStatus) Ext.TaskManager.stop(amdaDesktop.JobsMgr.updateStatus); amdaDesktop.JobsMgr.updateStatus = null; switch (this.get('jobType')) { case 'condition' : var type = 'Data Mining '; break; case 'request' : var type = 'Plot '; break; case 'download' : var type = 'Download '; break; case 'statistics' : var type = 'Statistics '; break; default: var type = 'unknown'; } var message = Ext.Date.format(new Date(), 'd-m-Y H:i:s: ') + ': '+ type + ' '+this.get('text') + ' killed'; myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.explorer.id, true, function (module) { module.addLogMessage(message); }); } //delete fieldset from Result Module if it is open else { var me = this; myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.result.id, true, function (module) { if (module && module.linkedNodes) { module.linkedNodes.each(function(item, index) { if (me.get('id') == item.get('id')) { module.removeLinkedNode(item, index); return false; } }, this); } }); } }, getObjectCallback : function(result,remoteEvent){ var t = remoteEvent.getTransaction(); //AKKA - Rework of the result treatment for the integration with the new kernel if (!remoteEvent.status) { myDesktopApp.errorMsg('Internal error during download request'); return; } if (!result.success) { myDesktopApp.errorMsg(result.message); return; } var obj = null; switch (this.get('jobType')) { case 'condition' : obj = Ext.create('amdaModel.Search', {name: result.name, resultId : result.result, folderId : result.folder}); break; case 'statistics' : obj = Ext.create('amdaModel.Stats', {name: result.name, resultId : result.result, folderId : result.folder}); break; case 'request' : obj = Ext.create('amdaPlotObj.PlotRequestObject', {name: result.name, format: result.format, resultId : result.result, folderId : result.folder}); break; case 'download' : obj = Ext.create('amdaModel.Download', {name: result.name, compression: result.compression, resultId : result.result, folderId : result.folder}); break; } if (!obj){ myDesktopApp.errorMsg("Unknown job type"); return; } // set parameter into node this.set('object',obj); var isInteractive = false; var isNewTab = true; this.editNode(isNewTab, isInteractive); }, // Show Result editNode : function(isNewTab, isInteractive) { var me = this; if (isInteractive) { myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.interactive_plot.id, true, function(module) { if (isNewTab) { module.setLinkedNode(me); } module.createWindow(); }); } else { myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.result.id, true, function(module) { if (isNewTab) { module.setLinkedNode(me); } module.createWindow(); }); } }, createJobNode: function(isResult) { // if ownerTree panel is not active if (this.myGetOwnerTree().ownerCt.getActiveTab() !== this.myGetOwnerTree()) { // set ownerTree panel as the active tab this.myGetOwnerTree().ownerCt.setActiveTab(this.myGetOwnerTree()); // to enable selection of this node his ownerTree must have a view } var rootNode = this.getRootNode(isResult); // expand the corresponding rootNode if (rootNode.parentNode) { if (!rootNode.parentNode.isExpanded()) { rootNode.parentNode.expand(false); } } if (!rootNode.isExpanded()) { rootNode.expand(false, function(){ if (!this.parentNode) { nodeFantom = rootNode.findChild('id',this.get('id')); if (nodeFantom) { nodeFantom.remove(); rootNode.appendChild(this); } } }, this); } else { rootNode.appendChild(this); } // select the new node this.myGetOwnerTree().getSelectionModel().select(this); if (!isResult) { switch (this.get('jobType')) { case 'condition' : var type = 'Data Mining '; break; case 'request' : var type = 'Plot '; break; case 'download' : var type = 'Download '; break; case 'statistics' : var type = 'Statistics '; break; default: var type = 'unknown'; } myDesktopApp.infoMsg('Your request is still running and has been assigned the name '+this.get('text')+' -- Check Jobs in Progress'); var message = Ext.Date.format(new Date(), 'd-m-Y H:i:s: ')+ type + ' '+this.get('text')+ ' created'; myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.explorer.id, true, function (module) { module.addLogMessage(message); }); amdaDesktop.JobsMgr.jobsInProgress++; if (!amdaDesktop.JobsMgr.updateStatus) { amdaDesktop.JobsMgr.updateStatus = Ext.TaskManager.start({ run : amdaDesktop.JobsMgr.getStatus, interval : amdaDesktop.JobsMgr.interval }); } } }, //override amdaModel.AmdaNode.getRootNode method getRootNode: function(isResult) { if (!this.get('rootNode')) { var rootNodeId; if (!isResult) { switch(this.get('jobType')) { case amdaModel.BkgJobNode.JOB_TYPES.PLOT: rootNodeId = amdaModel.BkgJobNode.JOB_ROOT_NODE.PLOT; break; case amdaModel.BkgJobNode.JOB_TYPES.CONDITION: rootNodeId = amdaModel.BkgJobNode.JOB_ROOT_NODE.CONDITION; break; case amdaModel.BkgJobNode.JOB_TYPES.DOWNLOAD: rootNodeId = amdaModel.BkgJobNode.JOB_ROOT_NODE.DOWNLOAD; break; case amdaModel.BkgJobNode.JOB_TYPES.STATISTICS: rootNodeId = amdaModel.BkgJobNode.JOB_ROOT_NODE.STATISTICS; break; default: break; } } else { switch(this.get('jobType')) { case amdaModel.BkgJobNode.JOB_TYPES.PLOT: rootNodeId = amdaModel.BkgJobNode.RES_ROOT_NODE.PLOT; break; case amdaModel.BkgJobNode.JOB_TYPES.CONDITION: rootNodeId = amdaModel.BkgJobNode.RES_ROOT_NODE.CONDITION; break; case amdaModel.BkgJobNode.JOB_TYPES.DOWNLOAD: rootNodeId = amdaModel.BkgJobNode.RES_ROOT_NODE.DOWNLOAD; break; case amdaModel.BkgJobNode.JOB_TYPES.STATISTICS: rootNodeId = amdaModel.BkgJobNode.RES_ROOT_NODE.STATISTICS; break; default: break; } } this.set('rootNode',this.myGetOwnerTree().getRootNode().findChild( 'id', rootNodeId, true)); } return this.get('rootNode'); }, /** * @override amdaModel.ExecutableNode.execute PNG (interactive session only!!!) */ execute : function(arguments) { // Not needed to send the whole request // var jsonObj = this.get('object').getJsonValues(true); //TODO append jsonObj.action at server side => history!!! var jsonObj = {}; var isMulti = arguments[0]; jsonObj.action = {name:arguments[1],arg1:arguments[2],arg2:arguments[3]}; //AKKA replace resultID by folderId jsonObj.folderId = this.get('object').get('folderId'); //jsonObj.resultId = this.get('object').get('resultFolder'); this.action = jsonObj.action.name; // this.set('tabId', jsonObj.tabId); // Node exists already, interactive Session var isInteractive = true; var isNewTab = false; loadMask.show(this.get('object').get('tabId')); AmdaAction.execute({nodeType : this.get('nodeType')}, jsonObj, function(res,e) { loadMask.hide(); //AKKA - Rework of the result treatment for the integration with the new kernel if (!e.status) { myDesktopApp.errorMsg('Internal error during request'); return; } if (!res.success) { myDesktopApp.errorMsg(res.message); return; } // NO background jobs for PNG !!!!! Timeout KILL if (res.status == amdaModel.BkgJobNode.STATUS_LIST.DONE) { this.updateNode(res); this.updateObject(res); this.editNode(isNewTab, isInteractive); } else { myDesktopApp.warningMsg(res.message); // keep this for case of Background Job /* var id = res.id; var text = 'job_' + res.pid; var status = amdaModel.BkgJobNode.STATUS_LIST.IN_PROGRESS; var newobj = Ext.create('amdaModel.Plot', { resultId : id, name : res.rawname, resultId: res.rawname}); var newNode = Ext.create(this.$className, { id : id, pid : res.pid, text : text, jobType : 'request', leaf : true, status : status, rawname : res.rawname, object : newobj}); newNode.createJobNode(false); */ } }, this); }, updateNode : function(res) { var windowId = 'plot' + this.get('tabId')+'-win'; var win = myDesktopApp.getDesktop().getWindow(windowId); //TODO if it is possible to close window before getting result? if (!win) myDesktopApp.errorMsg('You have closed window!!!'); else { var panelResult = win.items.items[0]; panelResult.setObjectIntoNode(); } }, updateObject : function(res) { var object = this.get('object'); object.set('outputName', res.name); object.set('resultId', res.result); object.set('startDate', res.startDate); object.set('stopDate', res.stopDate); if (object.get('timesrc') == amdaModel.AmdaTimeObject.inputTimeSrc[0] && this.action != 'zoom') { object.set('intervalN', res.intervalN); object.set('totalN', res.totalN); object.set('ttName', res.tableName); } } });