UNPKG

dl

Version:

DreamLab Libs

211 lines (181 loc) 6.29 kB
/** * @overview MySQLCredentialPool * @copyright Dreamlab Onet.pl sp. z. o o 2012 */ var MySQLPool = require('core').client.MySQLPool; var CredentialsManager = require('../credentials/Manager.js').CredentialsManager; var mysql = require('mysql'); /** * @class MySQLCredentialPool * @classdesc MySQL connection pool. * @param {String} credential credential key * @param {String} identity credential identity */ var MySQLCredentialPool = function (credential, identity) { var that = this; MySQLPool.call(this); this._credential = credential; this._cm = CredentialsManager.factory(identity); this._cm.addEventListener(CredentialsManager.Event.LOADED, credential, function (data) { that._createSpareClients(data.data); }); this._cm.addEventListener(CredentialsManager.Event.ERROR, credential, function (data) { console.error('CREDENTIAL ERROR: ' + credential + '. Error while receiving credential data for MySQLPool', JSON.stringify(data.data)); setTimeout(function () { console.info('CREDENTIAL INFO: getting credential -> ' + credential); that._cm.renewCredential(credential); }, 500); }); }; MySQLCredentialPool.prototype = Object.create(MySQLPool.prototype); /** * Create clients * @method */ MySQLCredentialPool.prototype.connect = function () { this._cm.getCredential(this._credential); }; /** * Create spare clients * @method * @param {Object} data */ MySQLCredentialPool.prototype._createSpareClients = function (data) { console.info('MySQLCredentialPool>MySQL create connections: %s', JSON.stringify(data)); var randIndex = Math.round(Math.random() * (data.hosts.length - 1)), host = data.hosts[randIndex].host, port = data.hosts[randIndex].port, max_connections = data.max_connections || 1; console.info('MySQLCredentialPool>MySQL connecting to: %s:%d', host, port); var create_connections = max_connections - this.getKnownLength(); console.info('MySQLCredentialPool>MySQL connections', (create_connections > 0 ? 'shortage' : 'overhead'), create_connections); var connectionOptions = { user: data.user, password: data.pass, host: host, port: port, database: data.db_name }; if (create_connections > 0) { this._createConnections(connectionOptions, create_connections); } else if (create_connections < 0) { /* * zamieniam liczbe ujemna na dodatnia, np.: * -5 = 5; * oznacza ze usuwamy 5 połaczeń */ create_connections = -create_connections; this._removeConnections(create_connections); } this._executeQueuedQueries(); }; /** * Usuwanie nadmiarowych polaczen * * @param {Number} n ilosc nadmiarowych polaczeń */ MySQLCredentialPool.prototype._removeConnections = function (n) { var that = this; for (var i = 0; i < n; i++) { if (this.getKnownLength() == 0) { break; } this.get(function (client) { that.markForDeletion(client); that.release(client); }); } }; /** * Tworzenie brakujacych polaczen * * @param {Object} connectionOptions - opcje dla polaczenia MySQL (host, port) * @param {Number} n - ilosc połączeń do utworzenia */ MySQLCredentialPool.prototype._createConnections = function (connectionOptions, n) { var toCount = n; var that = this; var isError = false; var onConnection = function (err) { if (err) { isError = true; } /* semafór */ if (--toCount) return; /* *** */ if (isError) { that._scheduleRenewCredential(); } }; for (var i = 0; i < n; i++) { this._createConnection(connectionOptions, onConnection); }; }; /** * Towrzenie pojedynczego połączenia do MySQL * * @param {Object} connectionOptions - opcje dla polaczenia MySQL (host, port) * @param {Function} callback - callback po zakonczeniu tworzenia połaczenia */ MySQLCredentialPool.prototype._createConnection = function (connectionOptions, callback) { var that = this; var client = mysql.createConnection(connectionOptions); var onConnectionError = function (error) { client.destroy(); callback(error); }; /* timeout connectu do MySQL */ var connectTimeout = setTimeout(function () { console.warn('MySQLCredentialPool>MySQL connection timeout'); that._removeClient(client); onConnectionError(new Error('MySQL Connection error')); }, 500); client.connect(function (err) { /* czyszcze timeout - udalo sie zakonczyc faze polączenia */ clearTimeout(connectTimeout); if (err) { console.warn('MySQLCredentialPool>MySQL connection error:', err); onConnectionError(err); } else { console.warn('MySQLCredentialPool>MySQL connection established'); callback(null); } }); client.on('close', function (err) { console.warn('MySQLCredentialPool>MySQL Close:', err); that._removeClient(client); }); client.on('error', function (err) { console.warn('MySQLCredentialPool>MySQL Error', err); }); client.query("SET NAMES utf8"); this.add(client); }; /** * Usuwanie klienta MySQL z puli. * Triggeruje odświeżenie credentiali. * * @param {MySQLClient} client - klient mysqla */ MySQLCredentialPool.prototype._removeClient = function (client) { this.markForDeletion(client); this.release(client); this._scheduleRenewCredential(); }; MySQLCredentialPool.prototype._scheduleRenewCredential = function () { /* jesli timer jest juz ustawiony to wychodze */ if (this._credentialTimer) return; var that = this; this._credentialTimer = setTimeout(function () { that._credentialTimer = null; that._cm.renewCredential(that._credential); }, 2500); }; MySQLCredentialPool.prototype.destroy = function () { this._cm.removeAllEventListeners(CredentialsManager.Event.LOADED); this._cm.removeAllEventListeners(CredentialsManager.Event.ERROR); }; exports.MySQLCredentialPool = MySQLCredentialPool;