code: function(opts){
      opts = opts || {};
  
      this.db = opts.db;
  
      this.config = {
          maxConnection : opts.maxConnection || DEFAULT_MAX_CONNECTION,
          connectionIdleTimeout : opts.connectionIdleTimeout || DEFAULT_CONNECTION_IDLE_TIMEOUT,
          maxPendingTask : opts.maxPendingTask || DEFAULT_MAX_PENDING_TASK,
          reconnectInterval : opts.reconnectInterval || DEFAULT_RECONNECT_INTERVAL,
  
          // allow concurrent request inside one connection, internal use only
          concurrentInConnection : opts.concurrentInConnection || false,
  
          // {shardId : {host : '127.0.0.1', port : 31017}}
          shards : opts.shards || {},
      };
  
      if(this.config.concurrentInConnection){
          this.config.maxConnection = 1;
      }
  
      var shardIds = Object.keys(this.config.shards);
      if(shardIds.length === 0){
          throw new Error('please specify opts.shards');
      }
  
      var shards = {};
      shardIds.forEach(function(shardId){
          shards[shardId] = {
              connections : {}, // {connId : connection}
              freeConnections : {}, // {connId : true}
              connectionTimeouts : {}, // {connId : timeout}
              pendingTasks : [],
              reconnectInterval : null,
          };
      });
      this.shards = shards;
  
      this.openConnectionLock = new AsyncLock({Promise : P, maxPending : 10000});
      this.collections = {};
  }
docs: Use one connection per transaction Route request to shards