Connection Pooling is a software design pattern used to manage a pool of database connections 
that can be shared among multiple client applications. The main objective of Connection Pooling 
is to reduce the overhead of creating new database connections for each client request, which 
can be time-consuming and resource-intensive. Instead, a Connection Pool maintains a fixed number 
of pre-established connections to the database, which can be reused by multiple client applications.
In a Connection Pool, clients request a connection from the pool when they need to interact with 
the database. The Connection Pool checks if there are any available connections in the pool. 
If a connection is available, the Connection Pool provides it to the client, and if not, 
the client is added to a waiting queue until a connection becomes available. When a client 
finishes using a connection, it is returned to the pool for reuse by another client, rather 
than being closed and destroyed.
The Connection Pooling design pattern provides several benefits, including improved performance and 
scalability, reduced overhead, and increased reliability and availability. By reusing existing 
connections instead of creating new ones, the Connection Pool can significantly reduce the 
time and resources required for establishing a new connection. Moreover, Connection Pooling can 
help reduce the risk of database connection errors due to resource exhaustion, especially in high-traffic applications.
ConnectionPool.js
class ConnectionPool {
    constructor(createConnection, maxConnections) {
        this.createConnection = createConnection;
        this.maxConnections = maxConnections;
        this.connections = [];
        this.waiting = [];
    }
    getConnection() {
        return new Promise((resolve, reject) => {
            if (this.connections.length < this.maxConnections) {
                const connection = this.createConnection();
                this.connections.push(connection);
                resolve(connection);
            } else {
                this.waiting.push({ resolve, reject });
            }
        });
    }
    releaseConnection(connection) {
        const index = this.connections.indexOf(connection);
        console.log("Are Same Connection", connection == this.connections[0])
        console.log("Index", index)
        console.log("Waiting List", this.waiting.length)
        this.getTotalConnections()
        if (index >= 0) {
            if (this.waiting.length > 0) {
                const { resolve } = this.waiting.shift();
                var newConnection = this.connections[index]
                if (connection.state === 'disconnected') {
                    //removing element from array
                    this.connections.splice(index, 1);
                    //create new connection
                    newConnection = this.createConnection()
                    this.connections.push(newConnection)
                    resolve(newConnection)
                } else {
                    resolve(newConnection)
                }
            }
        }
    }
    getTotalConnections() {
        console.log('Total connections are', this.connections.length)
    }
    closeAll() {
        console.log("Ending All connection")
        this.connections.forEach(connection => {
            connection.end();
        });
        this.connections = [];
        this.waiting.forEach(({ reject }) => {
            reject(new Error('Connection pool closed'));
        });
        this.waiting = [];
    }
}
module.exports = ConnectionPool;
Using ConnectionPool class to receive connections
const ConnectionPool = require('./ConnectionPool');
const mysql = require('mysql');
function createConnection() {
    var con = mysql.createConnection({
        host: "localhost",
        user: "root",
        password: "sangram#81",
        database: 'play'
    });
    con.connect(function (err) {
        if (err) throw err;
        console.log("Connected!");
    });
    return con;
}
const maxConnections = 1;
const pool = new ConnectionPool(createConnection, maxConnections);
pool.getConnection()
    .then(connection => {
        // Use the connection here
        connection.query('select * from cloth', function (error, results, fields) {
            if (error) throw error;
            console.log('The solution is: ', results);
        });
        setTimeout(() => {
            console.log("Releasing Connection")
            pool.releaseConnection(connection);
        }, 1000)
    })
    .catch(error => {
        console.error(error);
    })
    .finally(() => {
    });
pool.getConnection()
    .then(connection => {
        // Use the connection here
        connection.query('select * from cloth', function (error, results, fields) {
            if (error) throw error;
            console.log('The solution is: ', results);
        });
        setTimeout(() => {
            console.log("Releasing Connection")
            pool.releaseConnection(connection);
        }, 1000)
    })
    .catch(error => {
        console.error(error);
    })
    .finally(() => {
    });
pool.getConnection()
    .then(connection => {
        // Use the connection here
        connection.query('select * from cloth', function (error, results, fields) {
            if (error) throw error;
            console.log('The solution is: ', results);
        });
    })
    .catch(error => {
        console.error(error);
    })
    .finally(() => {
        pool.closeAll();
    });
 
No comments:
Post a Comment