7

以下は、私のクラスター Express アプリの簡略版です。

/index.js

module.exports = process.env.CODE_COV
    ? require('./lib-cov/app')
    : require('./lib/app');

/lib/app.js

var cluster = require('cluster'),
    express = require('express'),
    app = module.exports = express.createServer();

if (cluster.isMaster) {
    // Considering I have 4 cores.
    for (var i = 0; i < 4; ++i) {
        cluster.fork();
    }
} else {
    // do app configurations, then...

    // Don't listen to this port if the app is required from a test script.
    if (!module.parent.parent) {
        app.listen(8080);
    }
}

/test/test1.js

var app = require('../');

app.listen(7777);

// send requests to app, then assert the response.

質問:

  1. var app = require('../');このクラスター環境では動作しません。どのワーカー アプリを返す必要がありますか? Express アプリの代わりにクラスター オブジェクトを返す必要がありますか?
  2. ここで、明らかにテスト スクリプトでポートを設定しても機能しません。テスト スクリプト内のポートをアプリのクラスターにどのように設定しますか?
  3. このアプリのクラスターにどのようにリクエストを送信しますか?

考えられる唯一の解決策は、クラスタリング機能を条件付きでオフにし、アプリがテスト スクリプトから要求された場合に 1 つのアプリのみを実行することです ( if (module.parent.parent) ...)。

クラスター化された Express アプリを Mocha でテストする他の方法はありますか?

4

3 に答える 3

2

私はこれを行うためのはるかに簡単な方法を持っています

    if (process.env.NODE_ENV !== 'test') {
    if (cluster.isMaster) {
        var numCPUs = require('os').cpus().length;
        console.log('total cpu cores on this host: ', numCPUs);
        for (var i = 0; i < numCPUs; i++) {
            console.log('forking worker...');
            cluster.fork();
        }

        cluster.on('online', function(worker) {
            console.log('Worker ' + worker.process.pid + ' is online.');
        });
        cluster.on('exit', function(worker, code, signal) {
            console.log('worker ' + worker.process.pid + ' died.');
        });
    } else {
        console.log('Im a worker');
        // application code 
        setupServer()
    }
} else {
    // when running tests
    setupServer();
    }

testテストを実行するときは、必ず env を次のように設定してください。NODE_ENV=test grunt test

于 2015-10-08T16:53:06.547 に答える
0

シンプルなため、私はあなたのソリューションが好きでしたが、ノードのMVCフレームワークのような環境では、module.parentを最大11回(真剣に)チェーンすることになります。

より良いアプローチは、どのスクリプト ノードで処理が開始されたかを単純に確認することだと思います。ノードのコマンドライン引数は、process.argv で利用できます。この配列の最初の項目は「ノード」、実行可能ファイル、2 番目の引数はノードが実行を開始するファイルへのパスになります。あなたの場合、これは index.js になります。

だからチェックする代わりに

                   module.parent.parent
                            ^       ^        
                         (app.js)   |
                                (index.js)

あなたはこのようなことをすることができます

var starter = process.argv[1].split(path.sep).pop();

どこstarterにあるindexか、またはindex.jsサーバーを起動したものに応じて。 node index.jsnode index

チェックは次のようになります。

if (cluster.isMaster && starter === 'index.js') {
    cluster.fork();
}

私の環境で働いた - これが役に立てば幸いです!

于 2014-05-17T19:12:38.373 に答える