对nodejs中第三方模块generic-pool模块的一点改进

     generic-pool模块是nodejs的一个第三方模块,其作用为提供一个通用的连接池模块,可以通过generic-pool实现对tcp连接池或者mysql数据库连接池等的管理。github的地址如下:https://github.com/coopernurse/node-pool

      其基本的使用方法可以参照作者给的例子。

// Create a MySQL connection pool with
// a max of 10 connections and a 30 second max idle time
var poolModule = require('generic-pool');
var pool = poolModule.Pool({
    name     : 'mysql',
    create   : function(callback) {
        var Client = require('mysql').Client;
        var c = new Client();
        c.user     = 'scott';
        c.password = 'tiger';
        c.database = 'mydb';
        c.connect();

        // parameter order: err, resource
        // new in 1.0.6
        callback(null, c);
    },
    destroy  : function(client) { client.end(); },
    max      : 10,
    idleTimeoutMillis : 30000,
    log : true
});

// acquire connection - callback function is called
// once a resource becomes available
pool.acquire(function(err, client) {
    client.query("select * from foo", [], function() {
        // return object back to pool
        pool.release(client);
    });
});
示例的代码很简单。简要介绍一下。
name即该连接池的名称,这个变量用处不大。
create为一个函数对象,在该函数对象中需要给出连接建立的方法,变量c为连接句柄,通过c可以进行读写操作。callback(null,c)是必须有的,第一个参数可以是错误类型的变量,这样当连接建立错误时,不会把错误的连接进行计数。例如在创建连接时发生错误如果能触发error事件,那么callback可以改写成:
c.on("error",function(e){callback(e,c)});
callback(null,c);
destroy也是一个函数对象,实现的功能是释放连接句柄。
max为连接池中连接的最大数量。
idleTimeoutMills为连接失效时间,当一个连接的存活时间超过该失效时间时,连接会被销毁。
log为是否记录的标志符。
accquire即是对连接的调用。获取一个连接后,在回调函数中执行需要进行的逻辑。
    generc-pool小巧精悍,总共只有几百行,完全由js代码写成。使用的方法页很简单。但是有一点不足的地方是,实例A和实例B建立链接,初始化连接池poolAB之后,如果实例A在守护进程的作用下进行了重启,此时poolAB中的所有连接都会失效,但是generic-pool本身只对超时的连接进行了处理,对于这种虽然没有超时但是已经失效的连接并没有相应操作。这个缺陷为我的工作带来了极大困扰。我对该模块进行了小小的改动,实现了对失效链接的处理。
    其实就添加了一个函数:
function removeNotWritable() {
     var toKeep = [],
         i,
         al;
     // Go through the available (idle) items,
     // check if they are not writeable
     for (i = 0, al = availableObjects.length; i < al; i += 1) {
       if (availableObjects[i]["obj"]["writable"] != false &&  availableObjects[i]["obj"]["readable"] != false ) {
         // Client is writeable, so keep it.
         toKeep.push(availableObjects[i]);
       } else {
         // The client is not writeable, call it's destroyer.
   //      log("removeIdle() destroying obj - now:" + now + "not writeable");
         me.destroy(availableObjects[i].obj);
       }
     }
 
     // Replace the available items with the ones to keep.
     availableObjects = toKeep;
     al = availableObjects.length;
 }
这个函数遍历了连接池中所有现存的连接句柄,判断是否可读可写,若不可以,则证明该连接失效,删除此连接。在dispense()函数的如下位置调用该函数即可实现对失效连接的销毁。
 function dispense() {
       ......
    if (waitingCount > 0) {
      removeNotWritable();
      if (availableObjects.length > 0) {
 
  

你可能感兴趣的:(对nodejs中第三方模块generic-pool模块的一点改进)