/*
 * Retrieve a client that is connected and authenticated
 * to the specified hostname and port. Will reuse an existing connection if one is available.
 */
voltdb::Client
ConnectionPool::acquireClient(
        std::string hostname,
        std::string username,
        std::string password,
        StatusListener *listener,
        unsigned short port,
        ClientAuthHashScheme sha)
throw (voltdb::Exception, voltdb::ConnectException, voltdb::LibEventException) {
    LockGuard guard(m_lock);
    ClientSet *clients = reinterpret_cast<ClientSet*>(pthread_getspecific(m_borrowedClients));
    if (clients == NULL) {
        clients = new ClientSet();
        pthread_setspecific( m_borrowedClients, static_cast<const void *>(clients));
    }
    char portBytes[16];
    unsigned int portInt = port;
    snprintf(portBytes, 16, "%d", portInt);
    std::string identifier = hostname + "," + std::string(portBytes) + "," + username + "," + password;

    // if a thread calls acquireClient() multiple times with the same identifier, reuse the same client
    for (ClientSet::iterator i = clients->begin(); i != clients->end(); i++) {
        if ((*i)->m_identifier == identifier) {
            return (*i)->m_client;
        }
    }

    std::vector<boost::shared_ptr<ClientStuff> > *clientStuffs = &m_clients[identifier];

    while (clientStuffs->size() > 0) {
        boost::shared_ptr<ClientStuff> clientStuff = clientStuffs->back();
        clientStuffs->pop_back();

        // run the event loop once to verify the connection is still available
        clientStuff->m_client.runOnce();

        if (clientStuff->m_listener->m_connectionLost) {
            // if this connection is lost, try the next
            continue;
        } else {
            // otherwise return this connection
            clientStuff->m_listener->m_listener = listener;
            clients->push_back(clientStuff);
            return clientStuff->m_client;
        }
    }

    // no connection available, make a new one
    DelegatingStatusListener *delegatingListener = new DelegatingStatusListener();
    Client client = voltdb::Client::create(ClientConfig( username, password, delegatingListener, sha));
    client.createConnection(hostname, port);
    boost::shared_ptr<ClientStuff> stuff(new ClientStuff(client, identifier, delegatingListener));
    stuff->m_listener->m_listener = listener;
    clients->push_back(stuff);
    return client;
}
예제 #2
0
 void setUp() {
     m_dlistener = new boost::shared_ptr<DelegatingListener>(new DelegatingListener());
     m_voltdb.reset(new MockVoltDB(Client::create(ClientConfig("hello", "world", *m_dlistener))));
     m_client = m_voltdb->client();
 }