nyx_server
Version:
Node内容发布
161 lines (143 loc) • 4.52 kB
JavaScript
var log4js = require("log4js");
var Promise = require("bluebird");
var log = log4js.getLogger("ConnectionPool");
var _ = require("lodash");
var ConnectionPool = function (connectParams, timeout) {
this.busy = []; //在用连接
this.idl = []; //空闲连接
this.Max = 50; //最大连接数
this.requestQuene = []; //请求连接的队列。
this.timeout = timeout | 20000; //分配的超时时间
this.connectParams = connectParams;
};
/**
* 从连接池中得到一个连接
* @param {Object}connectParams 连接参数
* @param {Number}timeout 超时时间
*/
ConnectionPool.prototype.getConnection = function () {
var self = this;
return new Promise(function (resolve, reject) {
if (self.idl.length > 0) {
var connect = self.idl.shift();
self.busy.push(connect);
resolve(connect);
} else if ((self.busy.length + self.idl.length) < self.Max) {
try{
var connect = self._createConnection();
self.busy.push(connect);
resolve(connect);
}catch(err){
log.error("allocConnect 创建连接失败," + JSON.stringify(self.connectParams));
throw err;
};
} else {
self.requestQuene.push({
resolve: resolve,
reject: reject,
time: (new Date()).getTime()
});
}
});
};
/**
* 分配一个连接,这个方法应该由外部的定时器触发
* 异步处理连接。
*/
ConnectionPool.prototype.allocConnect = function () {
var self = this;
var request = this.requestQuene.shift();
if (!request) {
return;
}
if (this.idl.length > 0) {
var connect = this.idl.shift();
connect.vaild().then(function (valid) {
if (valid) {
self.busy.push(connect);
request.resolve(connect);
}else{
self.requestQuene.push(request);
}
});
} else if ((this.busy.length + this.idl.length) < this.Max) {
Promise.resolve(this._createConnection())
.then(function (connect) {
self.busy.push(connect);
request.resolve(connect);
}).catch(function (err) {
log.error("allocConnect 创建连接失败," + JSON.stringify(self.connectParams));
throw err;
});
} else {
this.requestQuene.push(request);
}
};
ConnectionPool.prototype.checkRequestTimeout = function () {
var requestQueue = [];
this.requestQuene.forEach(function (req) {
var time = req.time;
var now = (new Date()).getTime();
if (now - time > lastUseTime.getTime() > 2 * 60 * 1000) { //两分钟释放连接请求
req.reject(new Error("请求连接超时"));
} else {
requestQueue.push(req);
}
});
this.requestQuene = requestQueue;
};
ConnectionPool.prototype.checkBusy = function () {
var busy = [];
var _self = this;
this.busy.forEach(function (connection) {
var now = new Date();
var lastUseTime = connection.lastUseTime;
if (now.getTime() - lastUseTime.getTime() > 1 * 60 * 1000) { //两分钟
_self.idl.push(connection);
} else {
busy.push(connection);
}
});
this.busy = busy;
};
ConnectionPool.prototype.release = function (connect) {
var index = this.busy.indexOf(connect);
if (index >= 0) {
var c = this.busy.splice(index, 1);
this.idl.push(c[0]);
} else {
console.log("release 未找到匹配的连接");
}
};
ConnectionPool.prototype.close = function (connect) {
var index = this.busy.indexOf(connect);
if (index >= 0) {
this.busy.splice(index, 1);
}
index = this.idl.indexOf(connect);
if (index >= 0) {
this.idl.splice(index, 1);
}
};
/**
* 清除连接池。
* @param {boolean}force 是否强制清除
*/
ConnectionPool.prototype.clean = function (force) {
this.idl.forEach(function (connect) {
connect.end();
});
this.busy.forEach(function (connect) {
connect.end();
});
this.idl = [];
this.busy = [];
};
ConnectionPool.prototype.getState = function () {
return {
idl: this.idl.length,
busy: this.busy.length,
requestQuene: this.requestQuene.length
};
};
module.exports = ConnectionPool;