initPools() {
    const config = this.config;

    if (!config.replication) {
      this.pool = Pooling.createPool({
        create: () => this._connect(config).catch(err => err),
        destroy: mayBeConnection => {
          if (mayBeConnection instanceof Error) {
            return Promise.resolve();
          }

          return this._disconnect(mayBeConnection)
            .tap(() => { debug('connection destroy'); });
        },
        validate: config.pool.validate
      }, {
        Promise: config.pool.Promise,
        testOnBorrow: true,
        autostart: false,
        max: config.pool.max,
        min: config.pool.min,
        acquireTimeoutMillis: config.pool.acquire,
        idleTimeoutMillis: config.pool.idle,
        evictionRunIntervalMillis: config.pool.evict
      });

      debug(`pool created with max/min: ${config.pool.max}/${config.pool.min}, no replication`);

      return;
    }

    let reads = 0;

    if (!Array.isArray(config.replication.read)) {
      config.replication.read = [config.replication.read];
    }

    // Map main connection config
    config.replication.write = _.defaults(config.replication.write, _.omit(config, 'replication'));

    // Apply defaults to each read config
    config.replication.read = _.map(config.replication.read, readConfig =>
      _.defaults(readConfig, _.omit(this.config, 'replication'))
    );

    // custom pooling for replication (original author @janmeier)
    this.pool = {
      release: client => {
        if (client.queryType === 'read') {
          return this.pool.read.release(client);
        } else {
          return this.pool.write.release(client);
        }
      },
      acquire: (priority, queryType, useMaster) => {
        useMaster = _.isUndefined(useMaster) ? false : useMaster;
        if (queryType === 'SELECT' && !useMaster) {
          return this.pool.read.acquire(priority);
        } else {
          return this.pool.write.acquire(priority);
        }
      },
      destroy: mayBeConnection => {
        if (mayBeConnection instanceof Error) {
          return Promise.resolve();
        }

        return this.pool[mayBeConnection.queryType].destroy(mayBeConnection)
          .tap(() => { debug('connection destroy'); });
      },
      clear: () => {
        return Promise.join(
          this.pool.read.clear(),
          this.pool.write.clear()
        ).tap(() => { debug('all connection clear'); });
      },
      drain: () => {
        return Promise.join(
          this.pool.write.drain(),
          this.pool.read.drain()
        );
      },
      read: Pooling.createPool({
        create: () => {
          const nextRead = reads++ % config.replication.read.length; // round robin config
          return this
            ._connect(config.replication.read[nextRead])
            .tap(connection => {
              connection.queryType = 'read';
            })
            .catch(err => err);
        },
        destroy: connection => this._disconnect(connection),
        validate: config.pool.validate
      }, {
        Promise: config.pool.Promise,
        testOnBorrow: true,
        autostart: false,
        max: config.pool.max,
        min: config.pool.min,
        acquireTimeoutMillis: config.pool.acquire,
        idleTimeoutMillis: config.pool.idle,
        evictionRunIntervalMillis: config.pool.evict
      }),
      write: Pooling.createPool({
        create: () => {
          return this
            ._connect(config.replication.write)
            .tap(connection => {
              connection.queryType = 'write';
            })
            .catch(err => err);
        },
        destroy: connection => this._disconnect(connection),
        validate: config.pool.validate
      }, {
        Promise: config.pool.Promise,
        testOnBorrow: true,
        autostart: false,
        max: config.pool.max,
        min: config.pool.min,
        acquireTimeoutMillis: config.pool.acquire,
        idleTimeoutMillis: config.pool.idle,
        evictionRunIntervalMillis: config.pool.evict
      })
    };

    debug(`pool created with max/min: ${config.pool.max}/${config.pool.min}, with replication`);
  }
/**
   * Initialize connection pool. By default pool autostart is set to false, so no connection will be
   * be created unless `pool.acquire` is called.
   */
Initialize connection pool. By default pool autostart is set to false, so no connection will be
be created unless `pool.acquire` is called.
Initialize connection pool . By default pool autostart is set to false so no connection will be be created unless ` pool . acquire ` is called .
initPools() {
    const config = this.config;
    if (!config.replication) {
      this.pool = Pooling.createPool({
        create: () => this._connect(config).catch(err => err),
        destroy: mayBeConnection => {
          if (mayBeConnection instanceof Error) {
            return Promise.resolve();
          }
          return this._disconnect(mayBeConnection)
            .tap(() => { debug('connection destroy'); });
        },
        validate: config.pool.validate
      }, {
        Promise: config.pool.Promise,
        testOnBorrow: true,
        autostart: false,
        max: config.pool.max,
        min: config.pool.min,
        acquireTimeoutMillis: config.pool.acquire,
        idleTimeoutMillis: config.pool.idle,
        evictionRunIntervalMillis: config.pool.evict
      });
      debug(`pool created with max/min: ${config.pool.max}/${config.pool.min}, no replication`);
      return;
    }
    let reads = 0;
    if (!Array.isArray(config.replication.read)) {
      config.replication.read = [config.replication.read];
    }
    config.replication.write = _.defaults(config.replication.write, _.omit(config, 'replication'));
    config.replication.read = _.map(config.replication.read, readConfig =>
      _.defaults(readConfig, _.omit(this.config, 'replication'))
    );
    this.pool = {
      release: client => {
        if (client.queryType === 'read') {
          return this.pool.read.release(client);
        } else {
          return this.pool.write.release(client);
        }
      },
      acquire: (priority, queryType, useMaster) => {
        useMaster = _.isUndefined(useMaster) ? false : useMaster;
        if (queryType === 'SELECT' && !useMaster) {
          return this.pool.read.acquire(priority);
        } else {
          return this.pool.write.acquire(priority);
        }
      },
      destroy: mayBeConnection => {
        if (mayBeConnection instanceof Error) {
          return Promise.resolve();
        }
        return this.pool[mayBeConnection.queryType].destroy(mayBeConnection)
          .tap(() => { debug('connection destroy'); });
      },
      clear: () => {
        return Promise.join(
          this.pool.read.clear(),
          this.pool.write.clear()
        ).tap(() => { debug('all connection clear'); });
      },
      drain: () => {
        return Promise.join(
          this.pool.write.drain(),
          this.pool.read.drain()
        );
      },
      read: Pooling.createPool({
        create: () => {
          const nextRead = reads++ % config.replication.read.length; 
          return this
            ._connect(config.replication.read[nextRead])
            .tap(connection => {
              connection.queryType = 'read';
            })
            .catch(err => err);
        },
        destroy: connection => this._disconnect(connection),
        validate: config.pool.validate
      }, {
        Promise: config.pool.Promise,
        testOnBorrow: true,
        autostart: false,
        max: config.pool.max,
        min: config.pool.min,
        acquireTimeoutMillis: config.pool.acquire,
        idleTimeoutMillis: config.pool.idle,
        evictionRunIntervalMillis: config.pool.evict
      }),
      write: Pooling.createPool({
        create: () => {
          return this
            ._connect(config.replication.write)
            .tap(connection => {
              connection.queryType = 'write';
            })
            .catch(err => err);
        },
        destroy: connection => this._disconnect(connection),
        validate: config.pool.validate
      }, {
        Promise: config.pool.Promise,
        testOnBorrow: true,
        autostart: false,
        max: config.pool.max,
        min: config.pool.min,
        acquireTimeoutMillis: config.pool.acquire,
        idleTimeoutMillis: config.pool.idle,
        evictionRunIntervalMillis: config.pool.evict
      })
    };
    debug(`pool created with max/min: ${config.pool.max}/${config.pool.min}, with replication`);
  }
initPools ( ) { const config = this . config ; if ( ! config . replication ) { this . pool = Pooling . createPool ( { create : ( ) => this . _connect ( config ) . catch ( err => err ) , destroy : mayBeConnection => { if ( mayBeConnection instanceof Error ) { return Promise . resolve ( ) ; } return this . _disconnect ( mayBeConnection ) . tap ( ( ) => { debug ( 'connection destroy' ) ; } ) ; } , validate : config . pool . validate } , { Promise : config . pool . Promise , testOnBorrow : true , autostart : false , max : config . pool . max , min : config . pool . min , acquireTimeoutMillis : config . pool . acquire , idleTimeoutMillis : config . pool . idle , evictionRunIntervalMillis : config . pool . evict } ) ; debug ( ` ${ config . pool . max } ${ config . pool . min } ` ) ; return ; } let reads = 0 ; if ( ! Array . isArray ( config . replication . read ) ) { config . replication . read = [ config . replication . read ] ; } config . replication . write = _ . defaults ( config . replication . write , _ . omit ( config , 'replication' ) ) ; config . replication . read = _ . map ( config . replication . read , readConfig => _ . defaults ( readConfig , _ . omit ( this . config , 'replication' ) ) ) ; this . pool = { release : client => { if ( client . queryType === 'read' ) { return this . pool . read . release ( client ) ; } else { return this . pool . write . release ( client ) ; } } , acquire : ( priority , queryType , useMaster ) => { useMaster = _ . isUndefined ( useMaster ) ? false : useMaster ; if ( queryType === 'SELECT' && ! useMaster ) { return this . pool . read . acquire ( priority ) ; } else { return this . pool . write . acquire ( priority ) ; } } , destroy : mayBeConnection => { if ( mayBeConnection instanceof Error ) { return Promise . resolve ( ) ; } return this . pool [ mayBeConnection . queryType ] . destroy ( mayBeConnection ) . tap ( ( ) => { debug ( 'connection destroy' ) ; } ) ; } , clear : ( ) => { return Promise . join ( this . pool . read . clear ( ) , this . pool . write . clear ( ) ) . tap ( ( ) => { debug ( 'all connection clear' ) ; } ) ; } , drain : ( ) => { return Promise . join ( this . pool . write . drain ( ) , this . pool . read . drain ( ) ) ; } , read : Pooling . createPool ( { create : ( ) => { const nextRead = reads ++ % config . replication . read . length ; return this . _connect ( config . replication . read [ nextRead ] ) . tap ( connection => { connection . queryType = 'read' ; } ) . catch ( err => err ) ; } , destroy : connection => this . _disconnect ( connection ) , validate : config . pool . validate } , { Promise : config . pool . Promise , testOnBorrow : true , autostart : false , max : config . pool . max , min : config . pool . min , acquireTimeoutMillis : config . pool . acquire , idleTimeoutMillis : config . pool . idle , evictionRunIntervalMillis : config . pool . evict } ) , write : Pooling . createPool ( { create : ( ) => { return this . _connect ( config . replication . write ) . tap ( connection => { connection . queryType = 'write' ; } ) . catch ( err => err ) ; } , destroy : connection => this . _disconnect ( connection ) , validate : config . pool . validate } , { Promise : config . pool . Promise , testOnBorrow : true , autostart : false , max : config . pool . max , min : config . pool . min , acquireTimeoutMillis : config . pool . acquire , idleTimeoutMillis : config . pool . idle , evictionRunIntervalMillis : config . pool . evict } ) } ; debug ( ` ${ config . pool . max } ${ config . pool . min } ` ) ; }
Initialize connection pool.
Initialize connection pool .
// Map main connection config // Apply defaults to each read config // custom pooling for replication (original author @janmeier) // round robin config