node.js redis server, what happens when there are

2019-08-11 01:39发布

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);
    }

});

0条回答
登录 后发表回答