2012-03-01 3 views
0

クライアントレコードの更新要求に応答するnode.jsベースのhttpサーバーを作成しようとしています。これらの要求はサーバーにサーバー側の作業を依頼しますが、要求はサーバー側の作業が完了するまで待つ必要はありません。node.jsを使用して一度に1つのプロセスのみが実行されるようにプロセスをキューに入れる

私のコードは次のようになります。これは動作します

var http = require('http'); 
http.createServer(function (request, response) { 
    response.writeHead(200, {'Content-Type': 'text/plain'}); 
    var sys = require('util'), 
     exec = require('child_process').exec, 
     child; 

    var parsed_url = require('url').parse(request.url, true) ; 
    var query = parsed_url['query'] ; 
    var client_id = query['client_id'] ; 

    child = exec('some_tedious_server_side_calculation ' + client_id, 
       function (error, stdout, stderr) { 
       if (error !== null) { 
       console.log('exec error: ' + error); 
       } 
    }); 
    response.end('I will process ' + client_id + ' when I get around to it\n'); 
}).listen(8888); 

console.log('Server running at http://127.0.0.1:8888/'); 

が、execが非ブロッキングであるので、私は一度にすべての要求の洪水を得れば、私はプロセスの洪水がすべて同時にsome_tedious_server_side_calculationを実行してしまいます。同時プロセスが多すぎると、サーバーが圧倒されます。

代わりに、このようなプロセスを1つだけ同時に実行したいと思っています。これどうやってするの?

答えて

0

私はあなたの最善の策は、このタスクを達成するためにジョブキューのようなものを使用することだと思います。 Kueはこれに最適です。基本的には、ジョブをキューに入れ、ジョブの「完了」メソッドでHTTP応答を返すことです。 Kueでは、ワーカープロセスの数を作成することもできます。見てみな。

編集:

ジョブが完了するまで待つ必要はありません。あなたはまだ前に応答することができます。基本的には、KueまたはJavaScript配列(キューとして動作するかどうか)を使用する場合でも、これが可能です。

var myQueue = []; 
childCallback = function (error, stdout, stderr) { 
     if (error !== null) { 
     console.log('exec error: ' + error); 
     } 

     if (myQueue.length > 0) { 
     var cid = myQueue.shift(); 
     child = exec('some_tedious_server_side_calculation ' + clid, childCallback);  
     }     
} 

var http = require('http'); 
http.createServer(function (request, response) { 
    response.writeHead(200, {'Content-Type': 'text/plain'}); 
    var sys = require('util'), 
     exec = require('child_process').exec, 
     child; 

    var parsed_url = require('url').parse(request.url, true) ; 
    var query = parsed_url['query'] ; 
    var client_id = query['client_id'] ; 

    if (myQueue.length === 0) { 
     child = exec('some_tedious_server_side_calculation ' + client_id, childCallback);    
    } else { 
    myQueue.push(client_id); //something like this... maybe the actual command? 
    } 

    }); 
    response.end('I will process ' + client_id + ' when I get around to it\n'); 
}).listen(8888); 

console.log('Server running at http://127.0.0.1:8888/'); 

[OK]をクリックして、コードがどのように機能するかを確認できるように変更しました。重要な変更は次のとおりです。

  • 私はキューとして機能しているアレイを使用しています。
  • 私はexecの匿名コールバック関数を引き出しました。要するに

、それは次のように動作します。

  1. あなたはHTTPリクエストを取得します。
  2. キューが空の場合、長いタスクは実行されます。
  3. キューが空でない場合、タスクはエンキューされます。 4 execへのコールバックで、保留中のタスク(queue.length> 0)がある場合、1つのタスクがデキューされてexecされます。

これは意味がありますか?

+0

クライアントとのHTTPセッションを終了するまでジョブが完了するまで待ちたくはありません。クライアントはジョブを送信し、離れてジョブが完了することを期待しています。 – rlandster

+0

あなたが見せてくれるアルゴリズムは、私が念頭に置いていたものではありません。Web要求がなくなっても、キューに入れられたすべてのタスクを連続して実行したいと思っています。最初からコーディングするのではなく、node.jsに組み込まれたものがあれば、これを簡単に行うことができます。 – rlandster

+0

Node.jsにネイティブに組み込まれているものはありません。しかし、サードパーティのツールやライブラリがあります。あなたの要件を誤解しているか、あなたがそれらを誤解していない限り、Kueはそれらの1つであり、要件をうまく満たしています。 –

関連する問題