JobsMgr.js 7.29 KB
/**
 * Project  : AMDA-NG4
 * Name     : JobsMgr.js
 * @class   amdaDesktop.JobsMgr
 * @extends Ext.AbstractManager
 * @brief    Manages Jobs In Progress
 * @author  elena
 * @version $Id: JobsMgr.js 2759 2015-02-19 12:32:31Z elena $
 *******************************************************************************
 *    FT Id     :   Date   : Name - Description
 *******************************************************************************
 *  :           :28/01/2011:
 */

'use strict'
/* global AmdaAction, myDesktopApp, amdaDesktop, amdaModel, amdaUI */

/**
 * @typedef {{
 *   success:     boolean,
 *   id:          string
 *   name:        string
 *   status:      string
 *   jobType:     string
 *   info:        string
 *   start:       string
 *   stop:        string
 *   folder:      string
 *   result:      string
 *   format:      string
 *   compression: string
 *   sendToSamp:  boolean
 * }} Job
 */

/**
 * @typedef {{
 *   success:        boolean,
 *   nFinished:      number,
 *   nError:         number,
 *   nInProgress:    number,
 *   jobsFinished:   Array.<Job>,
 *   jobsInProgress: Array.<Job>
 * }} Result
 */

/**
 * @typedef {{
 *   status: boolean
 * }} Error
 */

Ext.define('amdaDesktop.JobsMgr', {
  extend: 'Ext.AbstractManager',
  first: true,
  interval: 10000,
  jobTree: null,
  jobsError: 0,
  jobsFinished: 0,
  jobsInProgress: 0,
  singleton: true,
  updateStatus: null,

  // TODO first => at login !!!
  getStatus: function () {
    AmdaAction.getJobs(

      /**
       * Callback function for AmdaAction.getJobs.
       * @param {Result} res Server response of the PROCESSRUNNINGINFO request.
       * @param {Error} error Error, if any.
       * @returns {void}
       */
      function (res, error) {
        // TODO Errors processing
        var message, strDate, type
        if (error.status && res.success && res.jobsFinished) {
          // Update from Server Jobs Running and Finished
          if (res.nFinished > 0 || res.nError) {
            Ext.Array.each(res.jobsFinished, function (job) {

              /**
               * Called asynchronously on each finished job
               * @param {Job} job The finished job.
               */
              if (job.status !== 'old') {
                switch (job.jobType) {
                  case 'condition':
                    type = 'Data Mining '
                    break
                  case 'request':
                    type = 'Plot '
                    break
                  case 'download':
                    type = 'Download '
                    break
                  case 'statistic':
                    type = 'Statistics '
                    break
                  default:
                    type = 'unknown'
                }
                strDate = Ext.Date.format(new Date(), 'd-m-Y H:i:s: ')
                message = strDate + type + ' ' + job.name + ' completed'
                myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.explorer.id, true,
                  function (mod) {
                    mod.addLogMessage(message)
                  })
              }
            })
          }

          if (amdaDesktop.JobsMgr.first && (res.nInProgress > 0 || res.nFinished > 0 || res.nError > 0)) {
            myDesktopApp.infoMsg('You have  ' + res.nFinished + ' new finished jobs, ' +
              res.nInProgress + ' jobs in progress ' +
              'and ' + res.nError + 'jobs in error')
          }

          amdaDesktop.JobsMgr.jobsInProgress = res.nInProgress
          amdaDesktop.JobsMgr.jobsFinished = res.nFinished
          amdaDesktop.JobsMgr.jobsError = res.nError

          if (res.nInProgress === 0 && amdaDesktop.JobsMgr.updateStatus) {
            Ext.TaskManager.stop(amdaDesktop.JobsMgr.updateStatus)
            amdaDesktop.JobsMgr.updateStatus = null
          }
          if (res.nInProgress > 0 && !amdaDesktop.JobsMgr.updateStatus) {
            amdaDesktop.JobsMgr.updateStatus =
              Ext.TaskManager.start({
                interval: amdaDesktop.JobsMgr.interval,
                run: amdaDesktop.JobsMgr.getStatus
              })
          }

          if ((res.nFinished > 0 || res.nError) && !amdaDesktop.JobsMgr.first && res.jobsFinished) {
            if (!amdaDesktop.JobsMgr.jobTree) {
              amdaDesktop.JobsMgr.jobTree = Ext.getCmp(amdaUI.ExplorerUI.JOB_TAB.TREE_ID)
            }

            Ext.Array.each(res.jobsFinished,

              /**
               * Called asynchronously on each finished job.
               * @param {Job} job The finished job.
               * @return {void}
               */
              function (job) {
                var bkgJob, jobRootNode, nodeToMove, resRootNode, root
                bkgJob = amdaModel.BkgJobNode
                root = amdaDesktop.JobsMgr.jobTree.getRootNode()
                switch (job.jobType) {
                  case 'condition':
                    resRootNode = root.findChild('id', bkgJob.RES_ROOT_NODE.CONDITION, true)
                    jobRootNode = root.findChild('id', bkgJob.JOB_ROOT_NODE.CONDITION, true)
                    break
                  case 'request':
                    resRootNode = root.findChild('id', bkgJob.RES_ROOT_NODE.PLOT, true)
                    jobRootNode = root.findChild('id', bkgJob.JOB_ROOT_NODE.PLOT, true)
                    break
                  case 'download':
                    resRootNode = root.findChild('id', bkgJob.RES_ROOT_NODE.DOWNLOAD, true)
                    jobRootNode = root.findChild('id', bkgJob.JOB_ROOT_NODE.DOWNLOAD, true)
                    break
                  case 'statistic':
                    resRootNode = root.findChild('id', bkgJob.RES_ROOT_NODE.STATISTICS, true)
                    jobRootNode = root.findChild('id', bkgJob.JOB_ROOT_NODE.STATISTICS, true)
                    break
                  default:
                    break
                }

                /*
                 * TODO check job sub tree is always expanded - after the first job is launched - there
                 * cannot be too many unfinished jobs on login so callback is not needed
                 */

                if (!resRootNode.parentNode.isExpanded()) {
                  resRootNode.parentNode.expand(false)
                }
                if (!jobRootNode.parentNode.isExpanded()) {
                  jobRootNode.parentNode.expand(false)
                }
                if (!jobRootNode.isExpanded()) {
                  jobRootNode.expand(false)
                }

                // AKKA - use processid to find job
                nodeToMove = jobRootNode.findChild('id', job.id, false)
                nodeToMove.set('status', job.status)
                nodeToMove.set('info', job.info)

                // TODO check if really job.status

                nodeToMove.set('iconCls', 'icon-' + job.status)
                jobRootNode.removeChild(nodeToMove)

                if (resRootNode.isExpanded()) {
                  resRootNode.appendChild(nodeToMove)
                } else {
                  resRootNode.expand(false, function () {
                    var wantedId = nodeToMove.get('processId')
                    if (!resRootNode.findChild('id', wantedId)) {
                      resRootNode.appendChild(nodeToMove)
                    }
                  })
                }
              })
          }
        }
        amdaDesktop.JobsMgr.first = false
      })
  }
})