All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.voltdb.jdbc.JDBC4ClientConnectionPool Maven / Gradle / Ivy

There is a newer version: 13.3.2-preview1
Show newest version
/* This file is part of VoltDB.
 * Copyright (C) 2008-2017 VoltDB Inc.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with VoltDB.  If not, see .
 */

package org.voltdb.jdbc;

import java.util.HashMap;

import org.voltcore.utils.ssl.SSLConfiguration;

/**
 * Provides support for database connection pooling, allowing for optimal application performance.
 * From benchmarking results, optimal TCP socket usage is attained when 50 threads share the same
 * socket, sending execution requests through it. The pool incorporate the logic necessary to issue
 * newly created connections or pre-existing connections in use to client threads, as well as proper
 * management of those connections (releasing resources, etc.).
 *
 * @author Seb Coursol (originally in exampleutils)
 * @since 2.0
 */
public class JDBC4ClientConnectionPool {
    private static final HashMap ClientConnections = new HashMap();

    /**
     * No instantiation allowed.
     */
    private JDBC4ClientConnectionPool() {
    }

    /**
     * Gets a client connection to the given VoltDB server(s).
     *
     * @param servers
     *            the list of VoltDB servers to connect to.
     * @param port
     *            the VoltDB native protocol port to connect to (usually 21212).
     * @param user
     *            the user name to use when connecting to the server(s).
     * @param password
     *            the password to use when connecting to the server(s).
     * @param isHeavyWeight
     *            the flag indicating callback processes on this connection will be heavy (long
     *            running callbacks). By default the connection only allocates one background
     *            processing thread to process callbacks. If those callbacks run for a long time,
     *            the network stack can get clogged with pending responses that have yet to be
     *            processed, at which point the server will disconnect the application, thinking it
     *            died and is not reading responses as fast as it is pushing requests. When the flag
     *            is set to 'true', an additional 2 processing thread will deal with processing
     *            callbacks, thus mitigating the issue.
     * @param maxOutstandingTxns
     *            the number of transactions the client application may push against a specific
     *            connection before getting blocked on back-pressure. By default the connection
     *            allows 3,000 open transactions before preventing the client from posting more
     *            work, thus preventing server fire-hosing. In some cases however, with very fast,
     *            small transactions, this limit can be raised.
     * @param reconnectOnConnectionLoss
     *            Attempts to reconnect to a node with retry after connection loss
     * @return the client connection object the caller should use to post requests.
     */
    public static JDBC4ClientConnection get(String[] servers, String user,
            String password, boolean isHeavyWeight, int maxOutstandingTxns, boolean reconnectOnConnectionLoss) throws Exception {
        return get(servers, user, password, isHeavyWeight, maxOutstandingTxns, reconnectOnConnectionLoss, null);
    }

    /**
     * Gets a client connection to the given VoltDB server(s).
     *
     * @param servers
     *            the list of VoltDB servers to connect to.
     * @param port
     *            the VoltDB native protocol port to connect to (usually 21212).
     * @param user
     *            the user name to use when connecting to the server(s).
     * @param password
     *            the password to use when connecting to the server(s).
     * @param isHeavyWeight
     *            the flag indicating callback processes on this connection will be heavy (long
     *            running callbacks). By default the connection only allocates one background
     *            processing thread to process callbacks. If those callbacks run for a long time,
     *            the network stack can get clogged with pending responses that have yet to be
     *            processed, at which point the server will disconnect the application, thinking it
     *            died and is not reading responses as fast as it is pushing requests. When the flag
     *            is set to 'true', an additional 2 processing thread will deal with processing
     *            callbacks, thus mitigating the issue.
     * @param maxOutstandingTxns
     *            the number of transactions the client application may push against a specific
     *            connection before getting blocked on back-pressure. By default the connection
     *            allows 3,000 open transactions before preventing the client from posting more
     *            work, thus preventing server fire-hosing. In some cases however, with very fast,
     *            small transactions, this limit can be raised.
     * @param reconnectOnConnectionLoss
     *            Attempts to reconnect to a node with retry after connection loss
     * @param sslConfig
     *            Contains properties - trust store path and password, key store path and password,
     *            used for connecting with server over SSL. For unencrypted connection, passed in ssl
     *            config is null
     * @return the client connection object the caller should use to post requests.
     * @see #get(String servers, int port, String user, String password, boolean isHeavyWeight, int
     *      maxOutstandingTxns, reconnectOnConnectionLoss)
     */
    public static JDBC4ClientConnection get(String[] servers, String user, String password, boolean isHeavyWeight,
            int maxOutstandingTxns, boolean reconnectOnConnectionLoss, SSLConfiguration.SslConfig sslConfig) throws Exception {
        String clientConnectionKeyBase = getClientConnectionKeyBase(servers, user, password,
                isHeavyWeight, maxOutstandingTxns, reconnectOnConnectionLoss);
        String clientConnectionKey = clientConnectionKeyBase;

        synchronized (ClientConnections) {
            if (!ClientConnections.containsKey(clientConnectionKey))
                ClientConnections.put(clientConnectionKey, new JDBC4ClientConnection(
                        clientConnectionKeyBase, clientConnectionKey, servers, user,
                        password, isHeavyWeight, maxOutstandingTxns, reconnectOnConnectionLoss,
                        sslConfig));
            return ClientConnections.get(clientConnectionKey).use();
        }
    }

    /**
     * Releases a connection. This method (or connection.close() must be called by the user thread
     * once the connection is no longer needed to release it back into the pool where other threads
     * can pick it up. Failure to do so will cause a memory leak as more and more new connections
     * will be created, never to be released and reused. The pool itself will run the logic to
     * decide whether the actual underlying connection should be kept alive (if other threads are
     * using it), or closed for good (if the calling thread was the last user of that connection).
     *
     * @param connection
     *            the connection to release back into the pool.
     */
    public static void dispose(JDBC4ClientConnection connection) {
        synchronized (ClientConnections) {
            connection.dispose();
            if (connection.users == 0)
                ClientConnections.remove(connection.key);
        }
    }

    /**
     * Generates a hash/key for a connection based on the given list of connection parameters
     *
     * @param servers
     *            the list of VoltDB servers to connect to in comma separated hostname[:port] format.
     * @param user
     *            the user name to use when connecting to the server(s).
     * @param password
     *            the password to use when connecting to the server(s).
     * @param isHeavyWeight
     *            the flag indicating callback processes on this connection will be heavy (long
     *            running callbacks).
     * @param maxOutstandingTxns
     *            the number of transactions the client application may push against a specific
     *            connection before getting blocked on back-pressure.
     * @param reconnectOnConnectionLoss
     *            Attempts to reconnect to a node with retry after connection loss
     * @return the base hash/key for the given connection parameter
     */
    private static String getClientConnectionKeyBase(String[] servers, String user,
            String password, boolean isHeavyWeight, int maxOutstandingTxns, boolean reconnectOnConnectionLoss) {
        String clientConnectionKeyBase = user + ":" + password + "@";
        for (int i = 0; i < servers.length; i++)
            clientConnectionKeyBase += servers[i].trim() + ",";
        clientConnectionKeyBase += "{"
                + Boolean.toString(isHeavyWeight) + ":" + Integer.toString(maxOutstandingTxns)
                + ":" + Boolean.toString(reconnectOnConnectionLoss) + "}";
        return clientConnectionKeyBase;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy