webtrack-server / module / lib / SubProcess.js
SubProcess.js
Raw
const exec = require('child_process').fork;
const path = require('path');
const log = require('./log');
const MAXCOUNT = 3;
const PROCESS_LIMIT = 20;



class SubProcess {

  constructor(){
    this.getRequest = this.getRequest.bind(this);
    this.FOLDERPATH = 'subprocess'
    this.tmpobj = null;
  }

  /**
   * [exec subprocess from specific process file on the project folder "subprocess"]
   * @param  {String} file     ["createDownloadFile", "saveUpload"]
   * @param  {Object} [arg={}] [Parameter to send on the SubProcess]
   * @param  {Integer} [memory=512] [Parameter to send on the SubProcess]
   * @return {Promise}
   */
  exec(file, arg={}, memory=512){
    return new Promise(async (resolve, reject)=>{
      try {
        if(this.isProgress) throw new Error('SubProcess is running');
        const node = exec(path.resolve(this.FOLDERPATH, file+'.js'), { cwd: process.cwd(), detached:true, execArgv: ['--stack-size=50000', '--max-old-space-size='+memory]});

        node.send(arg);
        node.on('message', res => this.getRequest(res, async (logMSG, response) => {
          if(logMSG!=null){
            log.msg(...['Subprocess', file].concat(logMSG));
          }else if (response!=null) {
            if(response.hasOwnProperty('error') && response.error != null){
              reject(response.error)
            }else if(response.hasOwnProperty('result') && response.result != null){
              resolve(response.result)
            }
          }
        }))
      } catch (err) {
        reject(err)
      }
    });
  }

  /**
   * [createDownloadFile // start the subprocess with the file subprocess/createDownloadFile.js]
   * @param  {Object} [arg={}]
   * @return {Promise}
   */
  createDownloadFile(arg={}){
    return this.exec('createDownloadFile', arg, 12288);
  }

  /**
   * [saveUpload // start the subprocess with the file subprocess/saveUpload.js]
   * @param  {Object} [arg={}]
   * @return {Promise}
   */
  saveUpload(arg={}){
    return new Promise(async (resolve, reject) => {
        let count = 0;
        let error = null
        do {
          try {
            count += 1;
            await this.exec('saveUpload', arg, 6144);
            break;
          } catch (err) {
            error = err;
          }
        } while (count<MAXCOUNT);
        if(count==MAXCOUNT){
          console.error(error);
          reject(error)
        }else{
          resolve();
        }
    });
  }

  /**
   * [response send response msg to the parent process]
   * @param  {Object} object [default: {}]
   */
  response(object={}){
    process.send(Object.assign({error: null, result: null}, object));
  }

  /**
   * [log send log msg to the parent process]
   * @return {[type]} [description]
   */
  log(){
    process.send({log: Object.values(arguments)});
  }

  /**
   * [getRequest handler to response log and msg from subprocess]
   * @param  {Object} res
   * @param  {Function} cb [Default: (log, response)=>{}]
   */
  getRequest(res={}, cb=(log, response)=>{}){
    if(res.hasOwnProperty('log')){
      cb(res.log, null)
    }else if(res.hasOwnProperty('error') && res.hasOwnProperty('result')){
      cb(null, res)
    }else{
      cb(res, null)
    }
  }

  close(error=false){
    setTimeout(()=> process.exit(error? 1: 0), 1000);
  }



}//class



module.exports = SubProcess;