<commit_before>var express = require('express');
var router = express.Router();
var openwhisk = require('openwhisk');
var bodyParser = require('body-parser');

const DockerBackend = require('./../dockerbackend.js');
const messages = require('./../messages');

const config = require("./../config.js") || {}; // holds node specific settings, consider to use another file, e.g. config.js as option
const burstOWService = process.env.BURST_OW_SERVICE || config.burstOWService; // max number of containers per host

var dockerhost = process.env.DOCKER_HOST || function() {
    throw "please set the DOCKER_HOST environmental variable, e.g. http://${MY_HOST_WITH_DOCKER_REST}:2375";
}();

var openwhiskApi = process.env.OPENWHISK_API || function() {
    throw "please set the OPENWHISK_API environmental variable pointing to openwhisk global, e.g. https://openwhisk.ng.bluemix.net/api/v1";
}();

console.log("DOCKERHOST: " + dockerhost);
console.log("OPENWHISK_API: " + openwhiskApi);

var backend = new DockerBackend({dockerurl: dockerhost});
var stringify = require('json-stringify-safe');

var request = require('request');
var url = require('url');

var PouchDB = require('pouchdb');
PouchDB.plugin(require('pouchdb-find'));

var db = new PouchDB('owl.db');


var uuid = require("uuid");

router.use(bodyParser.json());

const retry = require('retry-as-promised')

var retryOptions = {
  max: 5, 
  timeout: 12000, 
  match: [ 
    messages.TOTAL_CAPACITY_LIMIT
  ],
  backoffBase: 15000,
  backoffExponent: 1, 
  report: function(msg){ console.log(msg, ""); }, 
  name:  'Action invoke' 
};

/*
 * OpenWhisk action invoke local implementation
 * 
 * Create activation in db
 * 		if not blocking respond with activation
 * 
 * Invoke action on openwhisk local Docker backend
 * 		if backend throws "action missing" exception
 * 			get specified action from global openwhisk
 * 			update local action registry
 * 			update bursting service action registry
 * 			invoke action on openwhisk local Docker backend and return result
 * 			if blocking
 * 				update activation
 * 
 * 		if backend throws "total capacity limit" exception
 * 			delegate action to bursting service
 * 			update activation
 * 			if blocking
 * 				respond with result
 * 	
 * 	update activation	
 * 	if blocking
 * 		respond with result
 * 
 */
router.post('/namespaces/:namespace/actions/:actionName', invokeHandler);
router.post('/namespaces/:namespace/actions/:packageName/:actionName', invokeHandlerWithPackage);

function invokeHandlerWithPackage(req, res) {
  // concatenate /<namespace>/<packageName>/<actionName> and pass as action name
  req.params.actionName = '/' + req.params.namespace + '/' + req.params.packageName + '/' + req.params.actionName;
  invokeHandler(req, res);
}

function invokeHandler(req, res) {
  console.log("PATH: " + req.path);
  console.log("params: " + JSON.stringify(req.params));
  console.log("namespace: " + req.params.namespace);
  console.log("actionName: " + req.params.actionName);

  console.log("BODY: " + JSON.stringify(req.body));
  console.log("headers: " + JSON.stringify(req.headers));

  var start = new Date().getTime();
  
  function updateAndRespond(activation, result, err){
	  console.log("raw result: " + JSON.stringify(result));
	  console.log("activation: " + JSON.stringify(activation));
	  var response;
	  var rc = 200;
	  
	  if(err !== undefined){
	    console.log("err.error.error:" + JSON.stringify(err));
	    response = {
	        "result": {
	             error: err.error.error
	        },
	        "status": "action developer error",
	        "success": false
	    };
	    rc = 502;
	  }else{
	    response = {
	        result,
	        "status": "success",
	        "success": true
	    };
	  }
	  
	  db.get(activation.activationId).then(function(activationDoc) {
		  activationDoc.activation.response = response;
	      
	      //store activation in local db
	      db.put(activationDoc).then(function (doc) {
	   	   console.log("returned responss: " + JSON.stringify(doc));
	   	   if(req.query.blocking === "true"){
	   		console.log("responding: " + JSON.stringify(response));
	   		
	   		if(req.query.result === "true"){
		   		res.status(rc).send(activationDoc.activation.response.result);
		   	}else{
		   		res.status(rc).send(activationDoc.activation);
		   	}
	   	   }
	      }).catch(function (err) {
	    	  processErr(req, res, err);
	      });
		}).catch(function (err) {
			processErr(req, res, err);
		});
    }

  
    createActivationAndRespond(req, res, start).then((activation) => {
	  function invokeWithRetries(){
		console.log("starting invoke with retries");
      	retry(function() {return backend.invoke(req.params.actionName, req.body)}, retryOptions).then((result)=>{
  		  console.log("=========>>>> retry resolved  " + result);<commit_msg>added activation end and duration<commit_after>var express = require('express');
var router = express.Router();
var openwhisk = require('openwhisk');
var bodyParser = require('body-parser');

const DockerBackend = require('./../dockerbackend.js');
const messages = require('./../messages');

const config = require("./../config.js") || {}; // holds node specific settings, consider to use another file, e.g. config.js as option
const burstOWService = process.env.BURST_OW_SERVICE || config.burstOWService; // max number of containers per host

var dockerhost = process.env.DOCKER_HOST || function() {
    throw "please set the DOCKER_HOST environmental variable, e.g. http://${MY_HOST_WITH_DOCKER_REST}:2375";
}();

var openwhiskApi = process.env.OPENWHISK_API || function() {
    throw "please set the OPENWHISK_API environmental variable pointing to openwhisk global, e.g. https://openwhisk.ng.bluemix.net/api/v1";
}();

console.log("DOCKERHOST: " + dockerhost);
console.log("OPENWHISK_API: " + openwhiskApi);

var backend = new DockerBackend({dockerurl: dockerhost});
var stringify = require('json-stringify-safe');

var request = require('request');
var url = require('url');

var PouchDB = require('pouchdb');
PouchDB.plugin(require('pouchdb-find'));

var db = new PouchDB('owl.db');


var uuid = require("uuid");

router.use(bodyParser.json());

const retry = require('retry-as-promised')

var retryOptions = {
  max: 5, 
  timeout: 12000, 
  match: [ 
    messages.TOTAL_CAPACITY_LIMIT
  ],
  backoffBase: 15000,
  backoffExponent: 1, 
  report: function(msg){ console.log(msg, ""); }, 
  name:  'Action invoke' 
};

/*
 * OpenWhisk action invoke local implementation
 * 
 * Create activation in db
 * 		if not blocking respond with activation
 * 
 * Invoke action on openwhisk local Docker backend
 * 		if backend throws "action missing" exception
 * 			get specified action from global openwhisk
 * 			update local action registry
 * 			update bursting service action registry
 * 			invoke action on openwhisk local Docker backend and return result
 * 			if blocking
 * 				update activation
 * 
 * 		if backend throws "total capacity limit" exception
 * 			delegate action to bursting service
 * 			update activation
 * 			if blocking
 * 				respond with result
 * 	
 * 	update activation	
 * 	if blocking
 * 		respond with result
 * 
 */
router.post('/namespaces/:namespace/actions/:actionName', invokeHandler);
router.post('/namespaces/:namespace/actions/:packageName/:actionName', invokeHandlerWithPackage);

function invokeHandlerWithPackage(req, res) {
  // concatenate /<namespace>/<packageName>/<actionName> and pass as action name
  req.params.actionName = '/' + req.params.namespace + '/' + req.params.packageName + '/' + req.params.actionName;
  invokeHandler(req, res);
}

function invokeHandler(req, res) {
  console.log("PATH: " + req.path);
  console.log("params: " + JSON.stringify(req.params));
  console.log("namespace: " + req.params.namespace);
  console.log("actionName: " + req.params.actionName);

  console.log("BODY: " + JSON.stringify(req.body));
  console.log("headers: " + JSON.stringify(req.headers));

  var start = new Date().getTime();
  
  function updateAndRespond(activation, result, err){
	  console.log("raw result: " + JSON.stringify(result));
	  console.log("activation: " + JSON.stringify(activation));
	  var response;
	  var rc = 200;
	  
	  if(err !== undefined){
	    console.log("err.error.error:" + JSON.stringify(err));
	    response = {
	        "result": {
	             error: err.error.error
	        },
	        "status": "action developer error",
	        "success": false
	    };
	    rc = 502;
	  }else{
	    response = {
	        result,
	        "status": "success",
	        "success": true
	    };
	  }
	  
	  db.get(activation.activationId).then(function(activationDoc) {
              var end = new Date().getTime();
              activationDoc.activation.end = end;
              activationDoc.activation.duration = (end - activationDoc.activation.start);

              activationDoc.activation.response = response;
                  
	      
	      //store activation in local db
	      db.put(activationDoc).then(function (doc) {
	   	   console.log("returned responss: " + JSON.stringify(doc));
	   	   if(req.query.blocking === "true"){
	   		console.log("responding: " + JSON.stringify(response));
	   		
	   		if(req.query.result === "true"){
		   		res.status(rc).send(activationDoc.activation.response.result);
		   	}else{
		   		res.status(rc).send(activationDoc.activation);
		   	}
	   	   }
	      }).catch(function (err) {
	    	  processErr(req, res, err);
	      });
		}).catch(function (err) {
			processErr(req, res, err);
		});
    }

  
    createActivationAndRespond(req, res, start).then((activation) => {
	  function invokeWithRetries(){
		console.log("starting invoke with retries");
      	retry(function() {return backend.invoke(req.params.actionName, req.body)}, retryOptions).then((result)=>{
  		  console.log("=========>>>> retry resolved  " + result);
{'fraction_non_alphanumeric': 0.14384116693679092, 'fraction_numerical': 0.004659643435980551, 'mean_word_length': 3.451307484220018, 'pattern_counts': {'":': 10, '<': 9, '<?xml version=': 0, '>': 21, 'https://': 2, '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': '3259226', 'n_tokens_mistral': 3245, 'n_tokens_neox': 2969, 'n_words': 680}