Here's a puzzling problem for me.
this node.js server subscribe and gets messages.
Here's the code
var subscriber = redis.createClient(port, host);
var client = redis.createClient(port, host);
var domain = require('domain');
var requirejs = require('requirejs');
var count = 0;
requirejs(['my-generator'], function(MyGenerator) {
subscriber.subscribe('CHANNEL');
subscriber.on('message', function(channel, message) {
var data = JSON.parse(message);
var key = data.key;
var args = data.args;
count = count + 1;
console.log('1, ', 'count: ', count, 'key: ', key);
// do some stuff
var d = domain.create();
d.on('error', function (err) {
// do some logging
});
d.run(function() {
var myGenerator = MyGenerator(args);
var waitFunction = myGenerator.next().value;
console.log('2, ', 'count: ', count, 'key: ', key);
waitFunction(function() {
var result = myGenerator.next().value;
console.log('3, ', 'count: ', count, 'key: ', key);
client.publish(key, result);
});
});
});
});
I expect to see the following, and I see them most of the time in fact.
1, count: 1, key: key1
2, count: 1, key: key1
3, count: 1, key: key1
expiring, count: 1
1, count: 2, key: key2
2, count: 2, key: key2
3, count: 2, key: key2
expiring, count: 2
I sometimes see the following sequence, and I don't understand how it could happen.
1, count: 1, key: key1
2, count: 1, key: key1
1, count: 2, key: key2
2, count: 2, key: key2
3, count: 2, key: key2
expiring, count: 2
expiring, count: 2 (notice count 2 is shared, I guess my-script is modified in memory and shared, and wonder how to prevent it)
Following are other pieces of the puzzle..
/ my-generator.js
define([
'module',
'text!my-script.js',
'script-fn',
], function(module, myScript, scriptFn) {
var MyGenerator = function* (count) {
var scriptString = myScript; // + some other script
var context = scriptFn.context;
var fn = scriptFn.fn;
fn(scriptString);
var main = context.main;
main.count = count;
yield _.bind(main.wait, main);
var result; //something that I get by running fn
return result;
}
});
// script-fn.js
define([
'vm'
], function(vm) {
var sandbox = {};
var context = vm.createContext(sandbox);
var script = vm.createScript('(function(scriptString) { eval(scriptString) })');
var fn = script.runInContext(context);
return {
context: context,
fn: fn
};
});
// my-script.js
main = {
count: 0
};
var _ = requirejs('underscore');
var Backbone = requirejs('backbone');
main.messenger = new Backbone.Model();
_.extend(main, {
wait: function (callback) {
var timerId = _.delay(
main.expire,
3000
);
return main.messenger.once('done', callback);
}
});