2017-01-27 7 views
0

最近、ジェネリックプールパッケージをバージョン3にアップグレードしました。これは約束を利用しています。予期しない動作の違いにもかかわらず、私はそれを動作させることができました。Node.js接続プールでエラーが発生したときに無限ループが発生する

私が抱える問題は、エラー状態をテストすることです。私は故意にパスワードを間違って設定しています。テストすると、エラーが発生しても何かが作成機能を起動していることを示す「接続に失敗しました」という無限ループが発生します。プールを正しく構成しなかったか、不適切に取得していると思います。

ジェネリックプールファクトリ:接続エラーをトリガ

const poolFactory = { 
    create: function() { 
    return new Promise(function(resolve, reject) { 
     var client = mysql.createConnection({ 
     host: config.host, 
     user: config.user, 
     password: config.pass, 
     }); 
     client.connect(function(err) { 
     if (err != null) { 
      log.write('ERROR', "Connection Error: MySQL: " + err.message); 
      reject(err); 
     } else { 
      log.write('INFO', "MySQL Connection created."); 
      resolve(client); 
     } 
     }); 

    }) 
    }, 
    destroy: function(client) { 
    return new Promise(function(resolve) { 
     client.end(function(err) { 
     if (err != null) { 
      log.write('ERROR', "DB Error: MySQL: " + err.message); 
     } else { 
      log.write('INFO', "Database connection closed."); 
      resolve(); 
     } 
     }); 
    }) 
    } 
} 

const cp = genericPool.createPool(poolFactory); 

テストクエリ:私は

Connection Error: MySQL: ER_ACCESS_DENIED_ERROR: Access denied for user 'user'@'localhost' (using password: YES) 

cp.acquire().then(
    function(client) { 
    client.query('USE ' + config.db, function(err, results, fields) { 
     if (err != null) { 
     log.write('ERROR', "DB test error: MySQL: " + err.message); 
     } else { 
     log.write('INFO', "MySQL connection tested successfully."); 
     cp.release(client) 
     } 
    }); 
    }).catch(function(err) { 
    cp.release(client); 
    log.write('ERROR', "Pool Error: " + err.message); 
}); 

私のエラー・ログには、数百万行でいっぱいになります私はエラー条件をテストしているので、単一のエラーが予想されます。私は無限ループを得るために間違って何をしていますか?私は、拒否(誤解)がそれ以上の質問に答えることができない状態で約束をすると思われたと思いましたか?

誰でも正しい方向に向けることができますか?

いつもありがとうございます!

EDIT:誰かがこの問題を最初に気にしていれば問題を説明する完全なスクリプトです!コンソールは「ERROR MySQL接続エラー:ER_ACCESS_DENIED_ERROR:ユーザー 'devUser' @ 'localhost'(パスワードは:YES)のアクセスが拒否されました。再度、感謝します。

// Test App to show logging issue 

var pool = require('generic-pool'), 
    mysql = require('mysql') 

var config = { 
    port: 8880, 
    host: 'localhost', 
    user: 'devUser', 
    pass: 'wrong-pass', 
    db: 'node-app-db' 
} 

const poolConfig = { 
    max: 3 
}; 

const poolFactory = { 
    create: function() { 
    return new Promise(function(resolve, reject) { 
     var client = mysql.createConnection({ 
     host: config.host, 
     user: config.user, 
     password: config.pass, 
     }); 
     client.connect(function(err) { 
     if (err != null) { 
      console.log('ERROR', "MySQL Connection Error: " + err.message); 
      reject(err); 
     } else { 
      console.log('USAGE', "MySQL Connection created. " + cp.size + " of " + config.poolSize + " connections to DB in use."); 
      resolve(client); 
     } 
     }); 

    }) 
    }, 
    destroy: function(client) { 
    return new Promise(function(resolve) { 
     client.end(function(err) { 
     if (err != null) { 
      console.log('ERROR', "DB Error: MySQL: " + err.message); 
     } else { 
      console.log('USAGE', "Database connection closed. Pool contains ' + cp.size + ' more connections."); 
      resolve(); 
     } 
     }); 
    }) 
    } 
} 

const cp = pool.createPool(poolFactory, poolConfig); 

cp.acquire().then(
    function(client) { 
    client.query('USE ' + config.db, function(err, results, fields) { 
     if (err != null) { 
     console.log('ERROR', "DB test error: MySQL: " + err.message); 
     } else { 
     console.log('READY', "MySQL connection tested successfully. DataServer ready for connections."); 
     cp.release(client) 
     } 
    }); 
    }).catch(function(err) { 
    cp.release(client); 
    console.log('ERROR', "Pool Error: " + err.message); 
}); 
+0

約束は 'poolFactoryから返されます。その場合、「作成」は拒否されます...私はそれが 'cp.acquire()'から返された約束とどのように関係しているのかわかりません。答えを保持する可能性があるコードがありません。 –

+0

コードで私はあなたを示していない?または私のアプリに入れていないコード? – whiteatom

+0

うーん..これはおそらくパッケージに関するよくある問題であろう。 – whiteatom

答えて

0

githubの問題

の私の元の応答からのクロスポスティング@whiteatomねえ - うんあなたは「既知の問題」の土地をヒットしてきました...いくつかの歴史のための

... でv2の場合、​​へのコールはfactory.createへの1回のコールに直接関連付けられ、factory.createのエラーは​​にバブルします。 v3では、​​へのコールはfactory.createへのコールに縛られず、したがってfactory.createのエラーは意味的な意味を持たないため、​​コールにバブリングできませんでした。代わりにfactoryエラーは今少し合計するので

event emitters経由Pool自体を介して公開されていますpromise​​によって返されたが、唯一の原因、具体的acquireコールに関連するエラー(タイムアウトなど)、およびないので、どんなのをに拒否しますプール内の他のエラー。プールの一般的なエラーを捕捉するには、あなたが持っているPoolインスタンスにいくつかのイベントリスナーを付ける必要があります。

factory.createが拒否する約束しか返さない場合、プールがいくつかの無限ループで終わる可能性があるという問題はまだあります。これを回避するには、factory.create関数にバックオフ機能を組み込むことができます(これは少しハックですが、実際にはバックオフをプールに入れる方法を見つける必要があります)。

関連する問題