Exemple #1
0
void Codec20::writeExpirationParams(transport::Transport& t,uint64_t lifespan, uint64_t maxIdle) const {
	uint32_t lInt= (uint32_t) lifespan;
	uint32_t mInt= (uint32_t) maxIdle;
	if ( lInt != lifespan)
		throw HotRodClientException("lifespan exceed 32bit integer");
	if ( mInt != maxIdle)
		throw HotRodClientException("maxIdle exceed 32bit integer");
	t.writeVInt(lInt);
    t.writeVInt(mInt);
}
void ConnectionPool::invalidateObject(const InetSocketAddress& key, TcpTransport* val) {
    sys::ScopedLock<sys::Mutex> l(lock);
    bool maxTotalReached = hasReachedMaxTotal();
    if (val != NULL) {
		// Remove from busy queue
		std::map<InetSocketAddress, TransportQueuePtr>::iterator busyIt = busy.find(key);
		if (busyIt == busy.end()) {
			throw HotRodClientException("No busy queue for address!");
		}

		busyIt->second->remove(val);
		totalActive--;

		if (maxTotalReached && !allocationQueue.empty()) {
			InetSocketAddress keyToAllocate = allocationQueue.front();
			allocationQueue.pop(); //front does not remove it...
			//we need to allocate a new connection for other key.
			idle[keyToAllocate]->push(&factory->makeObject(keyToAllocate));
			totalIdle++;
		}

		// Destroy object
		factory->destroyObject(key, *val);
    }
}
void ConnectionPool::invalidateObject(const InetSocketAddress& key, TcpTransport* val) {
    sys::ScopedLock<sys::Mutex> l(lock);
    if (val != NULL) {        
		// Remove from busy queue
		std::map<InetSocketAddress, TransportQueuePtr>::iterator busyIt = busy.find(key);
		if (busyIt == busy.end()) {
			throw HotRodClientException("No busy queue for address!");
		}
		busyIt->second->remove(val);
		// Destroy object
		factory->destroyObject(key, *val);
		// Add new transport to idle queue
		std::map<InetSocketAddress, TransportQueuePtr>::iterator idleIt = idle.find(key);
		if (idleIt == idle.end()) {
			throw HotRodClientException("No idle queue for address!");
		}
		idleIt->second->push(&factory->makeObject(key));
    }
}
TcpTransport& ConnectionPool::borrowObject(const InetSocketAddress& key) {
    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 = 0;
    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() < (size_t) 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;
}
Exemple #5
0
void Codec20::checkForErrorsInResponseStatus(Transport& transport, HeaderParams& params, uint8_t status) const {
    try {
        switch (status) {
        case HotRodConstants::INVALID_MAGIC_OR_MESSAGE_ID_STATUS:
        case HotRodConstants::REQUEST_PARSING_ERROR_STATUS:
        case HotRodConstants::UNKNOWN_COMMAND_STATUS:
        case HotRodConstants::SERVER_ERROR_STATUS:
        case HotRodConstants::COMMAND_TIMEOUT_STATUS:
        case HotRodConstants::UNKNOWN_VERSION_STATUS: {
            // If error, the body of the message just contains a message
            std::string msgFromServer = transport.readString();
            if (msgFromServer.find("SuspectException") != std::string::npos || msgFromServer.find("SuspectedException") != std::string::npos) {
                // Handle both Infinispan's and JGroups' suspicions
                // TODO: This will be better handled with its own status id in version 2 of protocol
                throw RemoteNodeSuspectException(msgFromServer, params.messageId, status);
            } else {
                throw HotRodClientException(msgFromServer); //, params.messageId, status);
            }
        }
        default: {
            throw InternalException("Unknown status: " + status);
        }
        }
    } catch (const Exception &) {
        // Some operations require invalidating the transport
        switch (status) {
        case HotRodConstants::INVALID_MAGIC_OR_MESSAGE_ID_STATUS:
        case HotRodConstants::REQUEST_PARSING_ERROR_STATUS:
        case HotRodConstants::UNKNOWN_COMMAND_STATUS:
        case HotRodConstants::UNKNOWN_VERSION_STATUS: {
            transport.invalidate();
        }
        }
        throw;
    }
}
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;
}