Skip to content

Commit

Permalink
- Users can define custom metadata via comments (must be valid yaml)
Browse files Browse the repository at this point in the history
- Added js-yaml dependency
  • Loading branch information
jungkumseok committed Jun 13, 2018
1 parent 2f1d141 commit 7060821
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 11 deletions.
45 changes: 35 additions & 10 deletions lib/core/CodeV3.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ var EventEmitter = require('events').EventEmitter;
var esprima = require('esprima');
var escodegen = require('escodegen');
var pidusage = require('pidusage');
var yaml = require('js-yaml');
var jsBeautify = require('js-beautify').js_beautify;
var chalk = require('chalk');
var Pubsub = require('./Pubsub.js');
Expand Down Expand Up @@ -580,19 +581,34 @@ Code.prototype.kill = function(){
})
}

Code._extractMeta = function(comments){
var meta = {};
for (var i=0; i < comments.length; i++){
if (comments[i].type === 'Block' && comments[i].value.indexOf('things.meta') === 0){
var body = comments[i].value.split('\n').slice(1,-1).join('\n');
meta = yaml.safeLoad(body);
break;
}
}
return meta;
}

/**
* Return instrumented code string
* @param {string} raw_code
*/
Code.instrument = function(pubsub, code_name, raw_code){
// var started = Date.now();
var ast = esprima.parse(raw_code);
var ast = esprima.parse(raw_code, { comment: true }); // Comment may contain meta info

var root_scope = new StaticScope('root'); // Create root scope (static scope)
var hook = new AstHook(root_scope, ast); // Process the AST

// Process metadata about the program
var meta = JSON.stringify(Code._extractMeta(ast.comments));

// Prepare the things-js template
var template_str = `(function(${SCOPE_PREFIX}){})(require('things-js').bootstrap('${pubsub.url}', '${code_name}'));`;
var template_str = `(function(${SCOPE_PREFIX}){})(require('things-js').bootstrap('${pubsub.url}', '${code_name}', ${meta}));`;
var template = esprima.parse(template_str);
// WARNING: the following depends on esprima output, and might break if esprima changes its format
template.body[0].expression.callee.body.body = ast.body;
Expand Down Expand Up @@ -643,7 +659,9 @@ Code.fromSnapshot = function(snapshot, dummy_pubsub){
content += Timer.generateCode(snapshot.timers[id]);
});

code.source = `(function(${SCOPE_PREFIX}){ ${content} })(require('things-js').bootstrap('${code.pubsub.url}', '${snapshot.meta.code_name}/${snapshot.meta.instance_id}'));`;
var meta = JSON.stringify(snapshot.meta.extra);

code.source = `(function(${SCOPE_PREFIX}){ ${content} })(require('things-js').bootstrap('${code.pubsub.url}', '${snapshot.meta.code_name}/${snapshot.meta.instance_id}', ${meta}));`;
// console.log(jsBeautify(code.source));
// code.source = jsBeautify(code.source);

Expand Down Expand Up @@ -1209,11 +1227,13 @@ ImmediateTimer.prototype.resume = ImmediateTimer.prototype.start;
var MasterIPCHandler = {
'init': function(proc, payload){
proc.id = payload.id;
proc.meta = payload.meta;
proc.status = Process.Status.RUNNING;
proc.emit('started', proc.id);
proc.code.pubsub.publish(PROGRAM_MONITOR_NAMESPACE, {
code_name: proc.code.name,
instance_id: proc.id,
meta: proc.meta,
status: proc.status,
source: proc.code.source
});
Expand Down Expand Up @@ -1257,6 +1277,7 @@ function Process(code, options, history){
var started, ended, elapsed;
self.code = code;
self.obj = child_process.fork(path.join(__dirname, 'vm.js'));
self.meta = {};

self.status = Process.Status.READY;
self.snapshots = [];
Expand Down Expand Up @@ -1541,16 +1562,17 @@ ProxyPubsub.prototype.publish = function(topic, message){
process.send({ ctrl: 'publish', payload: { topic: topic, message: message } });
}

function RootScope(pubsub_url, code_uri){
if (!(this instanceof RootScope)) return new RootScope(pubsub_url, code_uri);
function RootScope(pubsub_url, code_uri, user_meta){
if (!(this instanceof RootScope)) return new RootScope(pubsub_url, code_uri, user_meta);
Scope.call(this, null, null, null, null, SCOPE_PREFIX);
var self = this;
var identity = code_uri.split('/');
// this.uid = SCOPE_PREFIX;
this.meta = {
pubsub: (process.connected ? new ProxyPubsub(pubsub_url) : new Pubsub(pubsub_url) ),
code_name: identity[0],
instance_id: (identity[1] || helpers.randKey())
instance_id: (identity[1] || helpers.randKey()),
extra: user_meta
};
this.timers = {};
// this.root = undefined;
Expand All @@ -1559,7 +1581,7 @@ function RootScope(pubsub_url, code_uri){
this.console = new ProxyConsole(this);

if (process.connected){
process.send({ ctrl: 'init', payload: { id: this.meta.instance_id } });
process.send({ ctrl: 'init', payload: { id: this.meta.instance_id, meta: user_meta } });
process.on('message', function(message){
if (message.ctrl in RuntimeHandler){
var result = RuntimeHandler[message.ctrl](self, message.kwargs);
Expand Down Expand Up @@ -1593,15 +1615,18 @@ RootScope.prototype.snapshot = function(){
meta : {
pubsub: this.meta.pubsub.url,
code_name: this.meta.code_name,
instance_id: this.meta.instance_id
instance_id: this.meta.instance_id,
extra: this.meta.extra
},
timers: {},
tree: undefined
}

// Capture scope tree
var scope_tree = this.extractor();
snapshot.tree = scope_tree;

// Capture pending timer events
Object.values(this.timers).forEach(function(timer){
snapshot.timers[timer.id] = timer.getSerializable();
});
Expand Down Expand Up @@ -1699,8 +1724,8 @@ RootScope.prototype.clearInterval = RootScope.prototype.clearTimer;
RootScope.prototype.clearTimeout = RootScope.prototype.clearTimer;
RootScope.prototype.clearImmediate = RootScope.prototype.clearTimer;

Code.bootstrap = function(pubsub_url, code_uri){
return new RootScope(pubsub_url, code_uri);
Code.bootstrap = function(pubsub_url, code_uri, user_meta){
return new RootScope(pubsub_url, code_uri, user_meta);
}

module.exports = Code;
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"esprima": "^4.0.0",
"express": "^4.16.2",
"js-beautify": "^1.7.4",
"js-yaml": "^3.12.0",
"jsonschema": "^1.2.0",
"mongodb": "^2.2.33",
"mongoose": "^5.0.17",
Expand Down
2 changes: 1 addition & 1 deletion samples/motion_detector.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ var alarm_channel = 'things-videostream/alarm';
var threshold = 0.10;
/* end of configurable variables */

var pubsub = new things.Pubsub('motion-worker-1', pubsub_url);
var pubsub = new things.Pubsub(pubsub_url);

function formatTime(ms){
return ('00'+Math.floor((ms/1000) / 60).toString()).slice(-2)+":"+('00'+(Math.floor(ms/1000) % 60).toString()).slice(-2)+"."+('000'+(ms%1000)).slice(-3)
Expand Down

0 comments on commit 7060821

Please sign in to comment.