Как получить результаты асинхронного кода изнутри среды песочницы (vm2)?

Я работал над процессом, где мне нужно запустить несколько скриптов (внутри оболочки) в среде песочницы. Но подвох в том, что внутри этой обертки я буду запускать некоторый js-код (который я рассматриваю как собственную логику), используя eval ().

Чтобы добавить к этому больше, эта пользовательская логика, в свою очередь, содержит некоторые асинхронные манипуляции (выборка данных из mongodb).

Мне нужно выполнить весь этот процесс таким образом, чтобы процесс был синхронизирован и получил ответ в реальной среде (основной процесс), чтобы продолжить нормальный поток приложения, основанный на этом результате.

Примечание: для виртуальной среды я использую модуль VM2

Код настройки:

* Sandbox Script (основная оболочка) - sandboxScript.js

(function() { 
    console.log("Sandbox Environment");
   ........
   ........
   var ypAsync = require('async');
   const mongoConnector = require(sandboxModulesPath+'/mongo_manipulation_object');

   var result = {
      status : 0,
      body   : ''
   };

   ypAsync.series([function(callback){
        console.log("--------- Sandbox Sync1");
       //***************************************************
       //****** eval() to execute custom logic. ************
       //****** (contains fetching details from mongo) *****
       //***************************************************

        eval(script.userScript);

       //***************************************************
       //***************************************************
    },function(mongoResult,callback){
        console.log("--------- Sandbox Sync2");
        console.log(result);
        result.status = 200;
        result.body = mongoResult;

        callback(null,ypresponseAccessObj);

    }],function(err,finalResult){
        console.log("--------- Sandbox final Sync");
        console.log(finalResult);

        return finalResult;
    });
 })();

* Пользовательская логика (выполняется внутри eval ()) user.script

var mongoObject= new mongoConnector ('Demo Collection');
mongoObject.select("stmt",function(err,results){
    console.log("----- select() callback ------");
    console.log(err);
    console.log(results);  /*Able to get the results*/
    if(err){
      callback(err);
    }
    else{
      callback(err,results);   //Control needs to go to the next series 
                               //block of async.series in sandboxScript.js, 
                               //where eval was called. 
                               //But the results are not transferred*/
    }
 });

* Конфигурация узла Vm (основной процесс узла) - vmConfig.js

.......
.......
.......
//**** Read Sandbox helper script ****
var helper = fs.readFileSync(__dirname + '/../sandbox/sandboxScript.js', { 
encoding: "utf8" });
const {NodeVM, VMScript} = require('vm2');
        const vm = new NodeVM({
            sandbox: {
                sandboxModulesPath : __dirname + '/../sandbox',
                request : currentRequestObj,
                script: {
                    userScript: userScript
                } 
             sandbox: {
                sandboxModulesPath : __dirname + '/../sandbox',
                mongoDB : db, /* Passing Mongo DB instance to sandbox*/
                script: {
                    userScript: userScript
                } 
            },
            require: {
                    context: 'sandbox',
                    external: ['lodash','async','q'],
                    builtin: ['url','querystring'],   
                    root: "./"
                }
         });
        try{
            console.log("------ Main Process ------");
            var result = vm.run("module.exports = "+helper,'vmConfig.js');
            console.log(result); /* Result not received*/
            callback(null, result);
        }
        catch(e){
            console.log("Sandbox Error");
            console.log(e);
            callback(null, e.message);
        } 
.......
.......
.......

* Монго манипуляции - mongo_manipulation_object.js

let async = require('async');
function MongoManipulationObject(collectionName){
    console.log("************ In  MongoManipulationObject Constructor  ");
    this.collectionName= collectionName;

    this.remoteResponse = {
        "result" : []
    };
}

MongoManipulationObject.prototype.select = function(statement,callback){
    var self = this;
    async.waterfall([function(callback){
        // Connect to Mongo Collection to access details
        let collection = mongoDB.get().collection(self.collectionName);
        collection.find().toArray(function(err,documents){
            if(err){
                callback(err);
            }
            else{
                if(documents == null){
                    callback(null, "Empty");
                }else{
                    // console.log("Document Details");
                    callback(null, documents);
                }
            }
        });
    }],function(err,finalResult){
        // console.log("Final Callback");
        if(err){finalResult
            console.log(err);
            self.remoteResponse = err;
             callback(self.remoteResponse);
        }
        else{
            self.remoteResponse.result = finalResult;
            callback(null,self.remoteResponse); // send result back to 
                                                //select() in Custom Logic (user.script)
        }
    });
}

module.exports = MongoManipulationObject

0 ответов

Другие вопросы по тегам