Search in sources :

Example 1 with RuntimeRequestException

use of org.opendaylight.controller.cluster.access.concepts.RuntimeRequestException in project controller by opendaylight.

the class ClientTransactionCommitCohortTest method testOpFail.

/**
 * Test operation failure. Invokes given operation, which initiates message to the backend.
 * Received message is checked by expectFunction. Then replyFunction is invoked. One of the transactions in
 * cohort receives failure response.
 *
 * @param operation      operation
 * @param expectFunction expected message check
 * @param replyFunction  response function
 * @param <T>            type
 * @throws Exception unexpected exception
 */
private <T> void testOpFail(final Function<ClientTransactionCommitCohort, ListenableFuture<T>> operation, final Consumer<TransactionTester<RemoteProxyTransaction>> expectFunction, final Consumer<TransactionTester<RemoteProxyTransaction>> replyFunction) throws Exception {
    final ListenableFuture<T> canCommit = operation.apply(cohort);
    // reply success to all except last transaction
    replySuccess(transactions.subList(0, transactions.size() - 1), expectFunction, replyFunction);
    // reply fail to last transaction
    final TransactionTester<RemoteProxyTransaction> last = transactions.get(transactions.size() - 1);
    expectFunction.accept(last);
    final RuntimeException e = new RuntimeException();
    final RuntimeRequestException cause = new RuntimeRequestException("fail", e);
    last.replyFailure(cause);
    // check future fail
    final ExecutionException exception = assertOperationThrowsException(() -> getWithTimeout(canCommit), ExecutionException.class);
    Assert.assertEquals(e, exception.getCause());
}
Also used : RuntimeRequestException(org.opendaylight.controller.cluster.access.concepts.RuntimeRequestException) ExecutionException(java.util.concurrent.ExecutionException)

Example 2 with RuntimeRequestException

use of org.opendaylight.controller.cluster.access.concepts.RuntimeRequestException in project controller by opendaylight.

the class AbstractClientConnectionTest method testPoison.

@Test
public void testPoison() throws Exception {
    final Consumer<Response<?, ?>> callback = mock(Consumer.class);
    final Request<?, ?> request = createRequest(replyToProbe.ref());
    final ConnectionEntry entry = new ConnectionEntry(request, callback, 0L);
    connection.enqueueEntry(entry, 0L);
    connection.poison(new RuntimeRequestException("fail", new RuntimeException("fail")));
    verify(callback, timeout(1000)).accept(isA(TransactionFailure.class));
}
Also used : Response(org.opendaylight.controller.cluster.access.concepts.Response) TransactionFailure(org.opendaylight.controller.cluster.access.commands.TransactionFailure) RuntimeRequestException(org.opendaylight.controller.cluster.access.concepts.RuntimeRequestException) Test(org.junit.Test)

Example 3 with RuntimeRequestException

use of org.opendaylight.controller.cluster.access.concepts.RuntimeRequestException in project controller by opendaylight.

the class AbstractClientConnection method runTimer.

/**
 * Check this queue for timeout and initiate reconnection if that happened. If the queue has not made progress
 * in {@link #DEFAULT_NO_PROGRESS_TIMEOUT_NANOS} nanoseconds, it will be aborted.
 *
 * @param current Current behavior
 * @return Next behavior to use
 */
@VisibleForTesting
final ClientActorBehavior<T> runTimer(final ClientActorBehavior<T> current) {
    final Optional<Long> delay;
    lock.lock();
    try {
        haveTimer = false;
        final long now = currentTime();
        LOG.debug("{}: running timer on {}", context.persistenceId(), this);
        // The following line is only reliable when queue is not forwarding, but such state should not last long.
        // FIXME: BUG-8422: this may not be accurate w.r.t. replayed entries
        final long ticksSinceProgress = queue.ticksStalling(now);
        if (ticksSinceProgress >= context.config().getNoProgressTimeout()) {
            LOG.error("Queue {} has not seen progress in {} seconds, failing all requests", this, TimeUnit.NANOSECONDS.toSeconds(ticksSinceProgress));
            lockedPoison(new NoProgressException(ticksSinceProgress));
            current.removeConnection(this);
            return current;
        }
        // Requests are always scheduled in sequence, hence checking for timeout is relatively straightforward.
        // Note we use also inquire about the delay, so we can re-schedule if needed, hence the unusual tri-state
        // return convention.
        delay = lockedCheckTimeout(now);
        if (delay == null) {
            // We have timed out. There is no point in scheduling a timer
            LOG.debug("{}: connection {} timed out", context.persistenceId(), this);
            return lockedReconnect(current, new RuntimeRequestException("Backend connection timed out", new TimeoutException()));
        }
        if (delay.isPresent()) {
            // If there is new delay, schedule a timer
            scheduleTimer(delay.get());
        } else {
            LOG.debug("{}: not scheduling timeout on {}", context.persistenceId(), this);
        }
    } finally {
        lock.unlock();
    }
    return current;
}
Also used : RuntimeRequestException(org.opendaylight.controller.cluster.access.concepts.RuntimeRequestException) TimeoutException(java.util.concurrent.TimeoutException) VisibleForTesting(com.google.common.annotations.VisibleForTesting)

Example 4 with RuntimeRequestException

use of org.opendaylight.controller.cluster.access.concepts.RuntimeRequestException in project controller by opendaylight.

the class FrontendReadWriteTransaction method handleTransactionAbort.

private TransactionAbortSuccess handleTransactionAbort(final long sequence, final RequestEnvelope envelope, final long now) {
    if (state instanceof Open) {
        final ReadWriteShardDataTreeTransaction openTransaction = checkOpen();
        startAbort();
        openTransaction.abort(() -> {
            recordAndSendSuccess(envelope, now, new TransactionAbortSuccess(getIdentifier(), sequence));
            finishAbort();
        });
        return null;
    }
    if (ABORTING.equals(state)) {
        LOG.debug("{}: Transaction {} already aborting", persistenceId(), getIdentifier());
        return null;
    }
    if (ABORTED.equals(state)) {
        // We should have recorded the reply
        LOG.warn("{}: Transaction {} already aborted", persistenceId(), getIdentifier());
        return new TransactionAbortSuccess(getIdentifier(), sequence);
    }
    final Ready ready = checkReady();
    startAbort();
    ready.readyCohort.abort(new FutureCallback<Void>() {

        @Override
        public void onSuccess(final Void result) {
            recordAndSendSuccess(envelope, now, new TransactionAbortSuccess(getIdentifier(), sequence));
            finishAbort();
        }

        @Override
        public void onFailure(final Throwable failure) {
            recordAndSendFailure(envelope, now, new RuntimeRequestException("Abort failed", failure));
            LOG.warn("{}: Transaction {} abort failed", persistenceId(), getIdentifier(), failure);
            finishAbort();
        }
    });
    return null;
}
Also used : TransactionAbortSuccess(org.opendaylight.controller.cluster.access.commands.TransactionAbortSuccess) RuntimeRequestException(org.opendaylight.controller.cluster.access.concepts.RuntimeRequestException)

Example 5 with RuntimeRequestException

use of org.opendaylight.controller.cluster.access.concepts.RuntimeRequestException in project controller by opendaylight.

the class FrontendTransaction method handleRequest.

// Request order has already been checked by caller and replaySequence()
@SuppressWarnings("checkstyle:IllegalCatch")
@Nullable
final TransactionSuccess<?> handleRequest(final TransactionRequest<?> request, final RequestEnvelope envelope, final long now) throws RequestException {
    if (request instanceof IncrementTransactionSequenceRequest) {
        final IncrementTransactionSequenceRequest incr = (IncrementTransactionSequenceRequest) request;
        expectedSequence += incr.getIncrement();
        return recordSuccess(incr.getSequence(), new IncrementTransactionSequenceSuccess(incr.getTarget(), incr.getSequence()));
    }
    if (previousFailure != null) {
        LOG.debug("{}: Rejecting request {} due to previous failure", persistenceId(), request, previousFailure);
        throw previousFailure;
    }
    try {
        return doHandleRequest(request, envelope, now);
    } catch (RuntimeException e) {
        /*
             * The request failed to process, we should not attempt to ever
             * apply it again. Furthermore we cannot accept any further requests
             * from this connection, simply because the transaction state is
             * undefined.
             */
        LOG.debug("{}: Request {} failed to process", persistenceId(), request, e);
        previousFailure = new RuntimeRequestException("Request " + request + " failed to process", e);
        throw previousFailure;
    }
}
Also used : IncrementTransactionSequenceSuccess(org.opendaylight.controller.cluster.access.commands.IncrementTransactionSequenceSuccess) IncrementTransactionSequenceRequest(org.opendaylight.controller.cluster.access.commands.IncrementTransactionSequenceRequest) RuntimeRequestException(org.opendaylight.controller.cluster.access.concepts.RuntimeRequestException) Nullable(javax.annotation.Nullable)

Aggregations

RuntimeRequestException (org.opendaylight.controller.cluster.access.concepts.RuntimeRequestException)9 Test (org.junit.Test)4 ExecutionException (java.util.concurrent.ExecutionException)2 TimeoutException (java.util.concurrent.TimeoutException)2 TransactionFailure (org.opendaylight.controller.cluster.access.commands.TransactionFailure)2 RequestException (org.opendaylight.controller.cluster.access.concepts.RequestException)2 Response (org.opendaylight.controller.cluster.access.concepts.Response)2 VisibleForTesting (com.google.common.annotations.VisibleForTesting)1 Stopwatch (com.google.common.base.Stopwatch)1 Nullable (javax.annotation.Nullable)1 ConnectClientFailure (org.opendaylight.controller.cluster.access.commands.ConnectClientFailure)1 ConnectClientRequest (org.opendaylight.controller.cluster.access.commands.ConnectClientRequest)1 IncrementTransactionSequenceRequest (org.opendaylight.controller.cluster.access.commands.IncrementTransactionSequenceRequest)1 IncrementTransactionSequenceSuccess (org.opendaylight.controller.cluster.access.commands.IncrementTransactionSequenceSuccess)1 TransactionAbortSuccess (org.opendaylight.controller.cluster.access.commands.TransactionAbortSuccess)1 TransactionPurgeRequest (org.opendaylight.controller.cluster.access.commands.TransactionPurgeRequest)1 TransactionPurgeResponse (org.opendaylight.controller.cluster.access.commands.TransactionPurgeResponse)1 AbstractRequestTest (org.opendaylight.controller.cluster.access.concepts.AbstractRequestTest)1