2017-03-07 10 views
1

これは私をナットにしています。nodeJSを使用してS3からファイルをダウンロードできません。いくつかのファイルは終了しません。

私のサーバーは、S3からの比較的小さなファイル100個(最大2Mb)をダウンロードするのに必要です。

ファイルの95%は常に動作しますが、最後の6-8ファイルはブロックします。 resolverejectコールバックが、私は並行してファイルをダウンロードしようとした...

と呼ばれることはありませんますが...

  • 誰もがこれを経験しましたか?
  • パケットが失われてストリームが閉じないことがありますか?
  • 最大同時ダウンロード数はありますか?

ここでは技術的に例の95%で動作するコード、です:

let singleGetFromS3 = (bucket, fileName) => { 
    return new Promise((resolve, reject) => { 
     let extension = getFileNameExtension(fileName); 
     fs.stat(`./${fileName}`, (err, stat) => { 
     if (err === null) { 
      console.log(`${fileName} exists locally`); 
      resolve(fileName); 
     } else if(err.code === 'ENOENT') { 
      let params = {Bucket: bucket, Key: fileName}; 
      let file = require('fs').createWriteStream(`./tmp-${fileName}`); 
      s3.getObject(params).createReadStream() 
      .on('error', (error) => { return reject(error); }) 
      .on('end',() => { 
       fs.rename(`./tmp-${fileName}`, `./${fileName}`, reject); 
       return resolve(fileName); 
      }) 
      .pipe(file); 
     } else { 
      reject(err); 
     } 
     }); 
    }); 
    }; 

使用:

"aws-sdk": "^2.23.0", 
node --version 
v4.5.0 

答えて

2

あなたが解決するときに間違ったイベントをリッスンしているように見えます。すべてのバイトがS3のReadableから読み取られたときに解決したくない場合は、fileが書き込みを終えたときに解決したいと思います。

let singleGetFromS3 = (bucket, fileName) => { 
    return new Promise((resolve, reject) => { 
     let extension = getFileNameExtension(fileName); 
     fs.stat(`./${fileName}`, (err, stat) => { 
     if (err === null) { 
      console.log(`${fileName} exists locally`); 
      resolve(fileName); 
     } else if(err.code === 'ENOENT') { 
      let params = {Bucket: bucket, Key: fileName}; 
      let file = require('fs').createWriteStream(`./tmp-${fileName}`);  

      // Listen for the file to be done writing, then resolve 
      file.on('finish',() => { 
       fs.rename(`./tmp-${fileName}`, `./${fileName}`, reject); 
       return resolve(fileName); 
      }) 

      s3.getObject(params).createReadStream() 
      .on('error', (error) => { return reject(error); }) 
      .pipe(file); 
     } else { 
      reject(err); 
     } 
     }); 
    }); 
    }; 
+0

ありがとうございました。私はこれについて考えましたが、 'writeStream'が閉じられる理由は考えていませんでした。しかし、明らかにそれは動作しますが、まだ完成していない5〜6個のファイルがあります。:(:( –

+0

ところで、私はS3でのそのような簡単な操作がnodeJSのような痛みであることを知り、 ... –

+0

@AugustinRiedingerこれを簡略化したいのであれば、コールバック、イベント/ストリーム、約束をすべて同じ機能で利用しないことから始めたいのですが、bluebird.jsを使用して 'fs'を' promise 'する必要があります。 'fs.stat()'コールバックが必要です。また、私は答えを編集しました。私が最初に入れた '' close''イベントを使わず、代わりに '' finish''を使用してください。 – peteb

関連する問題