Skip to content

Instantly share code, notes, and snippets.

@formula1
Last active August 29, 2015 14:18
Show Gist options
  • Save formula1/c1aa2d81d4bb6b1b2dce to your computer and use it in GitHub Desktop.
Save formula1/c1aa2d81d4bb6b1b2dce to your computer and use it in GitHub Desktop.
vm timers and cancelling
var PassThrough = require("stream").PassThrough;
var temp = new PassThrough();
process.stdin.pipe(temp);
setImmediate(function(){
process.stdin.unpipe(temp);
});
var PassThrough = require("stream").PassThrough;
function cancelableSandBox(sandbox){
this.tm = [];
this.iv = [];
this.im = [];
this.pipes = {
stdin: new PassThrough(),
stdout: new PassThrough(),
stderr: new PassThrough()
};
var pipes = this.pipeAri = [];
this.pipes.stdin.on("pipe",function(stream){
pipes.push(stream);
})
this.pipes.stdin.on('unpipe', function(stream) {
pipes.splice(pipes.indexOf(stream),1);
});
if(sandbox) this.applyToSandbox(sandbox);
}
cancelableSandBox.prototype.applyToSandbox = function(sandbox){
var timeouts = this.tm;
var intervals = this.iv;
var immediates = this.im;
sandbox.process = this.pipes;
sandbox.console = new console.Console(sandbox.process.stdout, sandbox.process.stderr);
sandbox.setTimeout = function(script,time){
var args = Array.prototype.slice.call(arguments,2);
var tm = setTimeout(function(){
timeouts.splice(timeouts.indexOf(tm),1);
script.apply(script,args);
},time);
timeouts.push(tm);
return tm;
},
sandbox.clearTimeout = function(tm){
timeouts.splice(timeouts.indexOf(tm),1);
return clearTimeout(tm);
},
sandbox.setInterval = function(script,time){
var args = Array.prototype.slice.call(arguments,2);
var iv = setInterval(function(){
script.apply(script,args);
},time);
intervals.push(iv);
},
sandbox.clearInterval = function(iv){
intervals.splice(intervals.indexOf(iv),1);
return clearInterval(iv);
},
sandbox.setImmediate = function(script){
var args = Array.prototype.slice.call(arguments,1);
var im = setImmediate(function(){
immediates.splice(immediates.indexOf(im),1);
script.apply(script,args);
});
immediates.push(im);
},
sandbox.clearImmediate = function(im){
immediates.splice(immediates.indexOf(im),1);
return clearImmediate(im);
}
return sandbox;
}
cancelableSandBox.prototype.cancel = function(){
this.pipes.stdout.unpipe();
this.pipes.stderr.unpipe();
var stdin = this.pipes.stdin;
this.pipes.stdin.removeAllListeners("pipe");
this.pipes.stdin.removeAllListeners("unpipe");
var t;
while(t = this.pipeAri.pop()){
t.unpipe(stdin);
}
while(t = this.tm.pop()){
clearTimeout(t);
}
while(t = this.iv.pop()){
clearInterval(t);
}
while(t = this.im.pop()){
clearImmediate(t);
}
};
module.exports = cancelableSandBox;
var vm = require("vm");
var fs = require("fs");
var cancelableSandbox = require("./cancelableSandbox.js");
var s = new vm.Script(fs.readFileSync("./vmScript.js"));
var cs = new cancelableSandbox();
var sandbox = cs.applyToSandbox({});
var ctx = vm.createContext(sandbox);
sandbox.process.stdout.pipe(process.stdout);
sandbox.process.stderr.pipe(process.stderr);
process.stdin.pipe(sandbox.process.stdin);
s.runInContext(ctx);
setTimeout(function(){
console.log("canceling");
cs.cancel();
},1000);
setInterval(function(){
console.log("in interval");
setImmediate(function(){
console.log("Immediate after interval");
});
},50);
(function doAtSomePoint(){
var m = Math.floor(3*Math.random())+49;
console.log("in setTimeout");
setImmediate(function(){
console.log("Immediate after timeout");
});
setTimeout(doAtSomePoint,m);
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment