<commit_before>const fs = require('fs-extended');
const path = require('path');
const Promise = require('bluebird');
const dbConstants = require('../constants/db_constants');
const emailUtils = require('../utils/email_utils');
const workflowUtils = require('../utils/workflow_utils');
const ioUtils = require('../utils/io_utils');
const redis = require('../utils/redis');
const cccUtils = require('../utils/ccc_utils.js');
const statusConstants = require('molecular-design-applications-shared').statusConstants;

const runUtils = {

  setRunStatus(runId, status) {
    if (!statusConstants[status]) {
      return Promise.reject(`Unknown workflow status=${status}`);
    }

    return redis.hget(dbConstants.REDIS_RUNS, runId).then((runString) => {
      const run = JSON.parse(runString);
      const updatedRun = Object.assign({}, run, {
        status,
      });
      return redis.hset(
        dbConstants.REDIS_RUNS, runId, JSON.stringify(updatedRun)
      );
    });
  },

  sendEmailsWorkflowEnded(runId) {
    redis.hget(dbConstants.REDIS_RUNS, runId).then((runString) => {
      if (!runString) {
        return console.error(runString);
      }

      const run = JSON.parse(runString);

      return emailUtils.send(
        run.email,
        'Your Workflow Has Ended',
        './views/email_ended.ms',
        {
          runUrl: `${process.env.FRONTEND_URL}/workflow/${run.workflowId}/${run.id}`,
        }
      );
    }).catch(console.error.bind(console));
  },

  processJobFinished(jobResult) {
    const runId = jobResult.jobId;
    //Add the job id to all further log calls
    const log = global.log.child({f:'processJobFinished', runId:runId});
    log.debug({jobResult});
    // Check for errors in the job result
    // Set the final output and status on the run
    return redis.hget(dbConstants.REDIS_RUNS, runId).then((runString) => {
      const run = JSON.parse(runString);
      const status = jobResult.exitCode === 0 ?
        statusConstants.COMPLETED : statusConstants.ERROR;
      var outputs = [];
      for (var i = 0; i < jobResult.outputs.length; i++) {
        outputs.push({
          name: jobResult.outputs[i],
          type: 'url',
          value: jobResult.outputsBaseUrl + jobResult.outputs[i]
        });
      }
      const updatedRun = Object.assign({}, run, {
        outputs,
        status,
        jobResult,
        ended: Date.now(),
      });
      return redis.hset(
        dbConstants.REDIS_RUNS, runId, JSON.stringify(updatedRun)
      );
    })
    .catch(err => {
      return log.error({error:JSON.stringify(err)});
    })
    .then(ignored => {
      runUtils.sendEmailsWorkflowEnded(runId);
    });
  },

  waitOnJob(runId) {
    return cccUtils.promise()
      .then(ccc => {
        return ccc.getJobResult(runId);
      });
  },

  monitorRun(runId) {
    if (!runId) {
      log.error('Missing runId');
      throw "Missing runId";
    }
    log.debug('Monitoring run ' + runId);
    runUtils.waitOnJob(runId)
      .then(result => {
        //Get the job result, act on the result, send email, etc.
        return runUtils.processJobFinished(result);
      })
      .error(err => {
        log.error({message: `Failed to get job result runId=${runId}`});
        //Remove the job result
      });
  },

  executeWorkflow(workflowId, email, inputs) {
    const log = global.log.child({f:'executeWorkflow', workflowId:workflowId, email:email});
    var workflowPromise = null;
    switch(workflowId) {
      case '0':
          workflowPromise = workflowUtils.executeWorkflow0Step1(inputs);
          break;
      case '1':
          workflowPromise = workflowUtils.executeWorkflow1Step1(inputs);
          break;
      default:
        return Promise.reject({error:`No workflow for workflowId=${workflowId}`});
    }

    return workflowPromise
      .then(runId => {
        log.info({workflowId, runId});

        const runUrl = `${process.env.FRONTEND_URL}/workflow/${workflowId}/${runId}`;
        emailUtils.send(
          email,
          'Your Workflow is Running',
          'views/email_thanks.ms',
          { runUrl }
        )
        .catch(err => {
          log.error({message: 'Failed to send email', error:JSON.stringify(err).substr(0, 1000)});
        });
        //Record the runId with all the other data
        const emailPromise = redis.sadd(dbConstants.REDIS_WORKFLOW_EMAIL_SET, email);

        const runPayload = {
          id: runId,
          workflowId,
          email: email,
          created: Date.now(),
        };
        log.debug(JSON.stringify(runPayload).substr(0, 300));

        const runPromise = redis.hset(dbConstants.REDIS_RUNS, runId, JSON.stringify(runPayload));
        const statePromise = runUtils.setRunStatus(runId, statusConstants.RUNNING);

        return Promise.all([emailPromise, runPromise, statePromise]).then(() => {
          return runId;
        });
      })
      .then(runId => {
        if (!runId) {<commit_msg>Save inputs data on executing a workflow, to be passed back to the client on the results page<commit_after>const fs = require('fs-extended');
const path = require('path');
const Promise = require('bluebird');
const dbConstants = require('../constants/db_constants');
const emailUtils = require('../utils/email_utils');
const workflowUtils = require('../utils/workflow_utils');
const ioUtils = require('../utils/io_utils');
const redis = require('../utils/redis');
const cccUtils = require('../utils/ccc_utils.js');
const statusConstants = require('molecular-design-applications-shared').statusConstants;

const runUtils = {

  setRunStatus(runId, status) {
    if (!statusConstants[status]) {
      return Promise.reject(`Unknown workflow status=${status}`);
    }

    return redis.hget(dbConstants.REDIS_RUNS, runId).then((runString) => {
      const run = JSON.parse(runString);
      const updatedRun = Object.assign({}, run, {
        status,
      });
      return redis.hset(
        dbConstants.REDIS_RUNS, runId, JSON.stringify(updatedRun)
      );
    });
  },

  sendEmailsWorkflowEnded(runId) {
    redis.hget(dbConstants.REDIS_RUNS, runId).then((runString) => {
      if (!runString) {
        return console.error(runString);
      }

      const run = JSON.parse(runString);

      return emailUtils.send(
        run.email,
        'Your Workflow Has Ended',
        './views/email_ended.ms',
        {
          runUrl: `${process.env.FRONTEND_URL}/workflow/${run.workflowId}/${run.id}`,
        }
      );
    }).catch(console.error.bind(console));
  },

  processJobFinished(jobResult) {
    const runId = jobResult.jobId;
    //Add the job id to all further log calls
    const log = global.log.child({f:'processJobFinished', runId:runId});
    log.debug({jobResult});
    // Check for errors in the job result
    // Set the final output and status on the run
    return redis.hget(dbConstants.REDIS_RUNS, runId).then((runString) => {
      const run = JSON.parse(runString);
      const status = jobResult.exitCode === 0 ?
        statusConstants.COMPLETED : statusConstants.ERROR;
      var outputs = [];
      for (var i = 0; i < jobResult.outputs.length; i++) {
        outputs.push({
          name: jobResult.outputs[i],
          type: 'url',
          value: jobResult.outputsBaseUrl + jobResult.outputs[i]
        });
      }
      const updatedRun = Object.assign({}, run, {
        outputs,
        status,
        jobResult,
        ended: Date.now(),
      });
      return redis.hset(
        dbConstants.REDIS_RUNS, runId, JSON.stringify(updatedRun)
      );
    })
    .catch(err => {
      return log.error({error:JSON.stringify(err)});
    })
    .then(ignored => {
      runUtils.sendEmailsWorkflowEnded(runId);
    });
  },

  waitOnJob(runId) {
    return cccUtils.promise()
      .then(ccc => {
        return ccc.getJobResult(runId);
      });
  },

  monitorRun(runId) {
    if (!runId) {
      log.error('Missing runId');
      throw "Missing runId";
    }
    log.debug('Monitoring run ' + runId);
    runUtils.waitOnJob(runId)
      .then(result => {
        //Get the job result, act on the result, send email, etc.
        return runUtils.processJobFinished(result);
      })
      .error(err => {
        log.error({message: `Failed to get job result runId=${runId}`});
        //Remove the job result
      });
  },

  executeWorkflow(workflowId, email, inputs) {
    const log = global.log.child({f:'executeWorkflow', workflowId:workflowId, email:email});
    var workflowPromise = null;
    switch(workflowId) {
      case '0':
          workflowPromise = workflowUtils.executeWorkflow0Step1(inputs);
          break;
      case '1':
          workflowPromise = workflowUtils.executeWorkflow1Step1(inputs);
          break;
      default:
        return Promise.reject({error:`No workflow for workflowId=${workflowId}`});
    }

    return workflowPromise
      .then(runId => {
        log.info({workflowId, runId});

        const runUrl = `${process.env.FRONTEND_URL}/workflow/${workflowId}/${runId}`;
        emailUtils.send(
          email,
          'Your Workflow is Running',
          'views/email_thanks.ms',
          { runUrl }
        )
        .catch(err => {
          log.error({message: 'Failed to send email', error:JSON.stringify(err).substr(0, 1000)});
        });
        //Record the runId with all the other data
        const emailPromise = redis.sadd(dbConstants.REDIS_WORKFLOW_EMAIL_SET, email);

        const runPayload = {
          id: runId,
          workflowId,
          email: email,
          inputs,
          created: Date.now(),
        };
        log.debug(JSON.stringify(runPayload).substr(0, 300));

        const runPromise = redis.hset(dbConstants.REDIS_RUNS, runId, JSON.stringify(runPayload));
        const statePromise = runUtils.setRunStatus(runId, statusConstants.RUNNING);

        return Promise.all([emailPromise, runPromise, statePromise]).then(() => {
          return runId;
        });
      })
      .then(runId => {
        if (!runId) {
{'fraction_non_alphanumeric': 0.13894442223110756, 'fraction_numerical': 0.003398640543782487, 'mean_word_length': 2.5390873717721965, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2328338', 'n_tokens_mistral': 3077, 'n_tokens_neox': 3024, 'n_words': 610}