Search in sources :

Example 1 with StoreTimeoutException

use of voldemort.store.StoreTimeoutException in project voldemort by voldemort.

the class DynamicTimeoutStoreClient method putWithCustomTimeout.

/**
     * Performs a put operation with the specified composite request object
     * 
     * @param requestWrapper A composite request object containing the key and
     *        value
     * @return Version of the value for the successful put
     */
public Version putWithCustomTimeout(CompositeVoldemortRequest<K, V> requestWrapper) {
    validateTimeout(requestWrapper.getRoutingTimeoutInMs());
    List<Versioned<V>> versionedValues;
    long startTime = System.currentTimeMillis();
    String keyHexString = "";
    if (logger.isDebugEnabled()) {
        ByteArray key = (ByteArray) requestWrapper.getKey();
        keyHexString = RestUtils.getKeyHexString(key);
        logger.debug("PUT requested for key: " + keyHexString + " , for store: " + this.storeName + " at time(in ms): " + startTime + " . Nested GET and PUT VERSION requests to follow ---");
    }
    // We use the full timeout for doing the Get. In this, we're being
    // optimistic that the subsequent put might be faster such that all the
    // steps might finish within the allotted time
    requestWrapper.setResolveConflicts(true);
    versionedValues = getWithCustomTimeout(requestWrapper);
    Versioned<V> versioned = getItemOrThrow(requestWrapper.getKey(), null, versionedValues);
    long endTime = System.currentTimeMillis();
    if (versioned == null)
        versioned = Versioned.value(requestWrapper.getRawValue(), new VectorClock());
    else
        versioned.setObject(requestWrapper.getRawValue());
    // This should not happen unless there's a bug in the
    // getWithCustomTimeout
    long timeLeft = requestWrapper.getRoutingTimeoutInMs() - (endTime - startTime);
    if (timeLeft <= 0) {
        throw new StoreTimeoutException("PUT request timed out");
    }
    CompositeVersionedPutVoldemortRequest<K, V> putVersionedRequestObject = new CompositeVersionedPutVoldemortRequest<K, V>(requestWrapper.getKey(), versioned, timeLeft);
    putVersionedRequestObject.setRequestOriginTimeInMs(requestWrapper.getRequestOriginTimeInMs());
    Version result = putVersionedWithCustomTimeout(putVersionedRequestObject);
    long endTimeInMs = System.currentTimeMillis();
    if (logger.isDebugEnabled()) {
        logger.debug("PUT response received for key: " + keyHexString + " , for store: " + this.storeName + " at time(in ms): " + endTimeInMs);
    }
    return result;
}
Also used : Versioned(voldemort.versioning.Versioned) VectorClock(voldemort.versioning.VectorClock) CompositeVersionedPutVoldemortRequest(voldemort.store.CompositeVersionedPutVoldemortRequest) Version(voldemort.versioning.Version) StoreTimeoutException(voldemort.store.StoreTimeoutException) ByteArray(voldemort.utils.ByteArray)

Example 2 with StoreTimeoutException

use of voldemort.store.StoreTimeoutException in project voldemort by voldemort.

the class ClientRequestExecutorFactory method createAsync.

/**
     * Create a ClientRequestExecutor for the given {@link SocketDestination}.
     *
     * @param dest {@link SocketDestination}
     */
@Override
public void createAsync(final SocketDestination dest, final KeyedResourcePool<SocketDestination, ClientRequestExecutor> pool) throws Exception {
    int numCreated = created.incrementAndGet();
    if (logger.isDebugEnabled())
        logger.debug("Creating socket " + numCreated + " for " + dest.getHost() + ":" + dest.getPort() + " using protocol " + dest.getRequestFormatType().getCode());
    SocketChannel socketChannel = null;
    ClientRequestExecutor clientRequestExecutor = null;
    long durationMs = 0;
    try {
        socketChannel = SocketChannel.open();
        socketChannel.socket().setReceiveBufferSize(this.socketBufferSize);
        socketChannel.socket().setSendBufferSize(this.socketBufferSize);
        socketChannel.socket().setTcpNoDelay(true);
        socketChannel.socket().setSoTimeout(soTimeoutMs);
        socketChannel.socket().setKeepAlive(this.socketKeepAlive);
        socketChannel.configureBlocking(false);
        socketChannel.connect(new InetSocketAddress(dest.getHost(), dest.getPort()));
        if (logger.isDebugEnabled()) {
            logger.debug("Created socket " + numCreated + " for " + dest.getHost() + ":" + dest.getPort() + " using protocol " + dest.getRequestFormatType().getCode() + " after " + durationMs + " ms.");
        }
        ClientRequestSelectorManager selectorManager = selectorManagers[counter.getAndIncrement() % selectorManagers.length];
        Selector selector = selectorManager.getSelector();
        clientRequestExecutor = new ClientRequestExecutor(selector, socketChannel, socketBufferSize, idleConnectionTimeoutNs, dest);
        int timeoutMs = this.getTimeout();
        ProtocolNegotiatorClientRequest protocolRequest = new ProtocolNegotiatorClientRequest(dest.getRequestFormatType());
        NonblockingStoreCallback callback = new NonblockingStoreCallback() {

            @Override
            public void requestComplete(Object result, long requestTime) {
                if (result instanceof Exception) {
                    Exception e = (Exception) result;
                    /*
                         * There are 2 places where we can get a store timeout
                         * Exception
                         * 
                         * 1) While doing connect - the machine was up once, but
                         * not anymore. In that case, TCP SYN will be sent by
                         * the client, but server would not sent TCP ACK as it
                         * is dead.
                         * 
                         * 2) After connect doing Protocol Negotiation - Most
                         * likely the server and kernel is up, but the process
                         * is in a zombie state because of hard drive failure or
                         * stuck in shutdown or doing a GC. This can be
                         * intermittent or hard failures. Before this code
                         * change, if the process entered this state, Voldemort
                         * clients may not detect the failure immediately. They
                         * are treated as normal errors, instead of catastrophic
                         * erros.This was the reason before it is better to kill
                         * the process on a machine and let the machine stay up.
                         * After this code change they will be treated as
                         * connection failures ( catastrophic errors) to help
                         * recover the clients faster.
                         * 
                         * The second case can increase the false positives, but
                         * if a server is consistently timing out it is better
                         * to treat the server as dead and let the clients
                         * recover faster.
                         */
                    if (e instanceof StoreTimeoutException) {
                        e = new UnreachableStoreException("Error establishing connection for destination " + dest, new ConnectException(e.getMessage()));
                    }
                    if (logger.isDebugEnabled()) {
                        logger.debug("Reporting exception to pool " + e.getClass() + " for destination " + dest);
                    }
                    pool.reportException(dest, e);
                }
            }
        };
        NonblockingStoreCallbackClientRequest<String> clientRequest = new NonblockingStoreCallbackClientRequest<String>(pool, dest, protocolRequest, clientRequestExecutor, callback, stats);
        clientRequestExecutor.setConnectRequest(clientRequest, timeoutMs);
        selectorManager.add(clientRequestExecutor);
        selector.wakeup();
    } catch (Exception e) {
        // Make sure not to leak socketChannels
        if (socketChannel != null) {
            try {
                socketChannel.close();
            } catch (Exception ex) {
                if (logger.isEnabledFor(Level.WARN))
                    logger.warn(ex, ex);
            }
        }
        throw UnreachableStoreException.wrap("Error establishing connection for destination " + dest, e);
    }
    if (stats != null) {
        stats.incrementCount(dest, ClientSocketStats.Tracked.CONNECTION_CREATED_EVENT);
        stats.recordConnectionEstablishmentTimeUs(dest, durationMs * Time.US_PER_MS);
    }
}
Also used : SocketChannel(java.nio.channels.SocketChannel) InetSocketAddress(java.net.InetSocketAddress) ConnectException(java.net.ConnectException) StoreTimeoutException(voldemort.store.StoreTimeoutException) ClosedChannelException(java.nio.channels.ClosedChannelException) UnreachableStoreException(voldemort.store.UnreachableStoreException) ClosedSelectorException(java.nio.channels.ClosedSelectorException) NonblockingStoreCallback(voldemort.store.nonblockingstore.NonblockingStoreCallback) StoreTimeoutException(voldemort.store.StoreTimeoutException) UnreachableStoreException(voldemort.store.UnreachableStoreException) Selector(java.nio.channels.Selector) ConnectException(java.net.ConnectException)

Example 3 with StoreTimeoutException

use of voldemort.store.StoreTimeoutException in project voldemort by voldemort.

the class DynamicTimeoutStoreClient method deleteWithCustomTimeout.

/**
     * Performs a delete operation with the specified composite request object
     * 
     * @param deleteRequestObject Composite request object containing the key to
     *        delete
     * @return true if delete was successful. False otherwise
     */
public boolean deleteWithCustomTimeout(CompositeVoldemortRequest<K, V> deleteRequestObject) {
    List<Versioned<V>> versionedValues;
    validateTimeout(deleteRequestObject.getRoutingTimeoutInMs());
    boolean hasVersion = deleteRequestObject.getVersion() == null ? false : true;
    String keyHexString = "";
    if (!hasVersion) {
        long startTimeInMs = System.currentTimeMillis();
        if (logger.isDebugEnabled()) {
            ByteArray key = (ByteArray) deleteRequestObject.getKey();
            keyHexString = RestUtils.getKeyHexString(key);
            logger.debug("DELETE without version requested for key: " + keyHexString + " , for store: " + this.storeName + " at time(in ms): " + startTimeInMs + " . Nested GET and DELETE requests to follow ---");
        }
        // We use the full timeout for doing the Get. In this, we're being
        // optimistic that the subsequent delete might be faster all the
        // steps might finish within the allotted time
        deleteRequestObject.setResolveConflicts(true);
        versionedValues = getWithCustomTimeout(deleteRequestObject);
        Versioned<V> versioned = getItemOrThrow(deleteRequestObject.getKey(), null, versionedValues);
        if (versioned == null) {
            return false;
        }
        long timeLeft = deleteRequestObject.getRoutingTimeoutInMs() - (System.currentTimeMillis() - startTimeInMs);
        // getWithCustomTimeout
        if (timeLeft < 0) {
            throw new StoreTimeoutException("DELETE request timed out");
        }
        // Update the version and the new timeout
        deleteRequestObject.setVersion(versioned.getVersion());
        deleteRequestObject.setRoutingTimeoutInMs(timeLeft);
    }
    long deleteVersionStartTimeInNs = System.currentTimeMillis();
    if (logger.isDebugEnabled()) {
        ByteArray key = (ByteArray) deleteRequestObject.getKey();
        keyHexString = RestUtils.getKeyHexString(key);
        debugLogStart("DELETE", deleteRequestObject.getRequestOriginTimeInMs(), deleteVersionStartTimeInNs, keyHexString);
    }
    boolean result = store.delete(deleteRequestObject);
    if (logger.isDebugEnabled()) {
        debugLogEnd("DELETE", deleteRequestObject.getRequestOriginTimeInMs(), deleteVersionStartTimeInNs, System.currentTimeMillis(), keyHexString, 0);
    }
    if (!hasVersion && logger.isDebugEnabled()) {
        logger.debug("DELETE without version response received for key: " + keyHexString + ", for store: " + this.storeName + " at time(in ms): " + System.currentTimeMillis());
    }
    return result;
}
Also used : Versioned(voldemort.versioning.Versioned) StoreTimeoutException(voldemort.store.StoreTimeoutException) ByteArray(voldemort.utils.ByteArray)

Example 4 with StoreTimeoutException

use of voldemort.store.StoreTimeoutException in project voldemort by voldemort.

the class NonblockingStoreCallbackClientRequest method timeOut.

@Override
public void timeOut() {
    clientRequest.timeOut();
    invokeCallback(new StoreTimeoutException("ClientRequestExecutor timed out for destination " + destination), (System.nanoTime() - startNs) / Time.NS_PER_MS);
    executorPool.checkin(destination, clientRequestExecutor);
}
Also used : StoreTimeoutException(voldemort.store.StoreTimeoutException)

Aggregations

StoreTimeoutException (voldemort.store.StoreTimeoutException)4 ByteArray (voldemort.utils.ByteArray)2 Versioned (voldemort.versioning.Versioned)2 ConnectException (java.net.ConnectException)1 InetSocketAddress (java.net.InetSocketAddress)1 ClosedChannelException (java.nio.channels.ClosedChannelException)1 ClosedSelectorException (java.nio.channels.ClosedSelectorException)1 Selector (java.nio.channels.Selector)1 SocketChannel (java.nio.channels.SocketChannel)1 CompositeVersionedPutVoldemortRequest (voldemort.store.CompositeVersionedPutVoldemortRequest)1 UnreachableStoreException (voldemort.store.UnreachableStoreException)1 NonblockingStoreCallback (voldemort.store.nonblockingstore.NonblockingStoreCallback)1 VectorClock (voldemort.versioning.VectorClock)1 Version (voldemort.versioning.Version)1