2017-10-07 14 views
0

RetroPie-Setupという既存のシェルベースのフレームワークにフックするWebベースのツールを作成しています。NodeJS複数のexecFile呼び出しをキューに入れる

これらは、/RetroPie-Setup/retropie_packages.shというシェルスクリプトがあり、インストール、依存関係の取得、または異なるプログラムのコンパイルに使用できます。

1つの問題はpackages.shが特定の瞬間に複数回実行されるべきではないということです。そのため、一度に1つずつ実行されるキューをセットアップする必要があります。

複数の実行を防ぐためにpromise-queueを使用することはできますが、execFileを実行するたびにキュー内の場所に移動する代わりにすぐにコマンドを実行することになります。

downloadTest.sh(固有の名前を持つ10Mバイトのファイルをダウンロードします):

filename=test$(date +%H%M%S).db 
wget -O ${filename} speedtest.ftp.otenet.gr/files/test10Mb.db 
rm ${filename} 

ノードコード

const Queue = require('promise-queue') 
const { spawn,execFile } = require('child_process'); 
var maxConcurrent = 1; 
var maxQueue = Infinity; 
var que = new Queue(maxConcurrent, maxQueue); 

var testFunct = function(file) 
{ 
    var promise = new Promise((reject,resolve) => { 
     execFile(file,function(error, stdout, stderr) { 
      console.log('Finished executing'); 
      if(error) 
      { 
       reject(); 
      } else 
      { 
       resolve(stdout); 
      } 
     }); 
    }) 
    return promise; 
} 
var test1 = testFunct('/home/pi/downloadTest.sh') 
var test2 = testFunct('/home/pi/downloadTest.sh') 
var test3 = testFunct('/home/pi/downloadTest.sh') 
que.add(test1); 
que.add(test2); 
que.add(test3); 

答えて

1

あなたのコードされたここで

は私のサンプルコードです仕事に非常に近い。主な問題は、testFunct()を実行しており、Promiseがすぐにその内部にあるものの実行を開始するということです。これを解決するには、Function.prototype.bind()を使用して、パラメータを実行せずに関数にバインドします。このように:

que.add(testFunct.bind(null, '/home/pi/downloadTest.sh')); 
que.add(testFunct.bind(null, '/home/pi/downloadTest.sh')); 
que.add(testFunct.bind(null, '/home/pi/downloadTest.sh')); 

別の方法としては、今度はあなたがpromise-queueへの依存をドロップすることを可能にする、実装するキューが些細になりasync/awaitを使用することができます。

const execFile = require("util").promisify(require("child_process").execFile) 

(async function() { 
    let scripts = [ 
    "/home/pi/downloadTest.sh", 
    "/home/pi/downloadTest.sh", 
    "/home/pi/downloadTest.sh" 
    ] 

    for (let script of scripts) { 
    try { 
     let { stdout, stderr } = await execFile(script) 
     console.log("successfully executed script:", script) 
    } catch (e) { 
     // An error occured attempting to execute the script 
    } 
    } 
})() 

上記コードの興味深い部分はawait execFile(script)です。 await式を使用すると、execFile関数によって返されたPromiseが解決または拒否されるまで関数全体の実行が一時停止されます。つまり、順番に実行されるキューがあります。

関連する問題