Пример #1
0
bool ConnectionPool::tryRemoveIdle() {
	//first, if we find an idle queue with more the minIdle connection, we destroy one of them.
	//otherwise, we try to destroy and connection from the longer idle queue.
	const int minIdle = configuration.getMinIdle();

	do {
		const InetSocketAddress* keyToRemove = NULL;
		int longerQueueSize = 0;

		for (std::map<InetSocketAddress, TransportQueuePtr>::iterator it = idle.begin(); it != idle.end(); ++it) {
			TransportQueuePtr idleQ = it->second;
			if (minIdle > 0 && (int) idleQ->size() > minIdle) {
				keyToRemove = &it->first;
				break;
			} else if ((int) idleQ->size() > longerQueueSize) {
				keyToRemove = &it->first;
				longerQueueSize = idleQ->size();
			}
		}

		if (keyToRemove != NULL) {
			TcpTransport* t = NULL;
			if (idle[*keyToRemove]->poll(t)) { //in case of concurrent removal, avoid blocking
				factory->destroyObject(*keyToRemove, *t);
				totalIdle--;
				return true;
			}
		} else {
			return false;
		}
	} while (true);
}
Пример #2
0
void ConnectionPool::clear(const InetSocketAddress& key) {
    sys::ScopedLock<sys::Mutex> l(lock);
    TransportQueuePtr idleQ = idle[key];
    totalIdle -= idleQ->size();
    clear(key, idleQ);
    idle.erase(key);
}
Пример #3
0
int ConnectionPool::calculateMinIdleGrow(const InetSocketAddress& key) {
	TransportQueuePtr idleQ = idle[key];
	int grown = configuration.getMinIdle() - idleQ->size();
	//Note: if we need to check maxActive, uncomment the code above
	/*if (configuration.getMaxActive() > 0) {
		int growLimit = std::max(0, configuration.getMaxActive() - (int) busy[key]->size() - (int) idleQ->size());
		grown = std::min(grown, growLimit);
	}*/
	if (configuration.getMaxTotal() > 0) {
		int growLimit = std::max(0, configuration.getMaxTotal() - totalIdle - totalActive);
		grown = std::min(grown, growLimit);
	}
	return grown;
}
Пример #4
0
TcpTransport& ConnectionPool::borrowObject(const InetSocketAddress& key) {
    if (closed) {
        throw new HotRodClientException("Pool is closed");
    }
    if (!idle.count(key) || !busy.count(key)) {
        throw new HotRodClientException("Pool is closed");
    }
    TransportQueuePtr idleQ = idle[key];
    TransportQueuePtr busyQ = busy[key];

    // See if an object is readily available
    TcpTransport* obj;
    bool ok = idleQ->poll(obj);

    for (;;) {
        if (ok) {
            // Check if the object is still valid, if not destroy it
            if (configuration.isTestOnBorrow() && !factory->validateObject(key, *obj)) {
                factory->destroyObject(key, *obj);
                ok = false;
            }
            // We have a valid object
            if (ok) {
                busyQ->push(obj);
                break;
            }
        }
        // See if we can create a new one
        if (busyQ->size() < configuration.getMaxActive()) {
            obj = &factory->makeObject(key);
        } else {
            // Wait for an object to become idle
            obj = idleQ->pop();
        }
        ok = true;
    }
    factory->activateObject(key, *obj);
    return *obj;
}
Пример #5
0
TcpTransport& ConnectionPool::borrowObject(const InetSocketAddress& key) {
	sys::ScopedLock<sys::Mutex> l(lock);

    if (closed) {
        throw HotRodClientException("Pool is closed");
    }
    if (!idle.count(key) || !busy.count(key)) {
        throw HotRodClientException("Pool has no idle or no busy transports.");
    }
    TransportQueuePtr idleQ = idle[key];
    TransportQueuePtr busyQ = busy[key];

    // See if an object is readily available
    TcpTransport* obj = NULL;
    bool ok = idleQ->poll(obj);
    if (ok) {
        totalIdle--;
    }

    for (;;) {
        if (ok) {
            // Check if the object is still valid, if not destroy it
            if (configuration.isTestOnBorrow() && !factory->validateObject(key, *obj)) {
                factory->destroyObject(key, *obj);
                ok = false;
            }
            // We have a valid object
            if (ok) {
                busyQ->push(obj);
                totalActive++;
                break;
            }
        }
        // See if we can create a new one
        if (idleQ->size() == 0 && //the idle queue is empty
                (configuration.getMaxActive() < 0 || busyQ->size() < (size_t) configuration.getMaxActive()) && //max active not reached!
				!hasReachedMaxTotal()) {
            obj = &factory->makeObject(key);
		} else if (hasReachedMaxTotal()) {
			//max total reached. try to destroy a existing idle connection. if not possible, wait until some other connection is available.
			if (tryRemoveIdle()) { //removal successful.
				obj = &factory->makeObject(key);
			} else {
				allocationQueue.push(key);
				{
					sys::ScopedUnlock<sys::Mutex> u(lock);
					obj = idleQ->pop();
				}
				totalIdle--;
			}
		} else {
			// Wait for an object to become idle
			{
				sys::ScopedUnlock<sys::Mutex> u(lock);
				obj = idleQ->pop();
			}
			totalIdle--;
		}
		ok = true;
    }
    factory->activateObject(key, *obj);
    return *obj;
}
Пример #6
0
void ConnectionPool::clear(const InetSocketAddress& key, TransportQueuePtr queue) {
    while (queue->size() > 0) {
        TcpTransport* transport = queue->pop();
        factory->destroyObject(key, *transport);
    }
}