Search in sources :

Example 1 with PutException

use of com.google.appengine.api.search.PutException in project teammates by TEAMMATES.

the class SearchManager method putDocumentWithRetry.

/**
 * Tries putting a document, handling transient errors by retrying with exponential backoff.
 *
 * @throws PutException if a non-transient error is encountered.
 * @throws MaximumRetriesExceededException with final {@link OperationResult}'s message as final message,
 *         if operation fails after maximum retries.
 */
private static void putDocumentWithRetry(String indexName, final Document document) throws PutException, MaximumRetriesExceededException {
    final Index index = getIndex(indexName);
    /*
         * The GAE Search API signals put document failure in two ways: it either
         * returns a PutResponse containing an OperationResult with a non-OK StatusCode, or
         * throws a PutException that also contains an embedded OperationResult.
         * We handle both ways by examining the OperationResult to determine what kind of error it is. If it is
         * transient, we use RetryManager to retry the operation; if it is
         * non-transient, we do not retry but throw a PutException upwards instead.
         */
    RM.runUntilSuccessful(new RetryableTaskThrows<PutException>("Put document") {

        private OperationResult lastResult;

        @Override
        public void run() {
            try {
                PutResponse response = index.put(document);
                lastResult = response.getResults().get(0);
            } catch (PutException e) {
                lastResult = e.getOperationResult();
            }
        }

        @Override
        public boolean isSuccessful() throws PutException {
            // Update the final message to be shown if the task fails after maximum retries
            finalMessage = lastResult.getMessage();
            if (StatusCode.OK.equals(lastResult.getCode())) {
                return true;
            } else if (StatusCode.TRANSIENT_ERROR.equals(lastResult.getCode())) {
                // A transient error can be retried
                return false;
            } else {
                // A non-transient error signals that the operation should not be retried
                throw new PutException(lastResult);
            }
        }
    });
}
Also used : PutException(com.google.appengine.api.search.PutException) Index(com.google.appengine.api.search.Index) OperationResult(com.google.appengine.api.search.OperationResult) PutResponse(com.google.appengine.api.search.PutResponse)

Example 2 with PutException

use of com.google.appengine.api.search.PutException in project java-docs-samples by GoogleCloudPlatform.

the class Utils method indexADocument.

/**
 * Put a given document into an index with the given indexName.
 * @param indexName The name of the index.
 * @param document A document to add.
 * @throws InterruptedException When Thread.sleep is interrupted.
 */
// [START putting_document_with_retry]
public static void indexADocument(String indexName, Document document) throws InterruptedException {
    IndexSpec indexSpec = IndexSpec.newBuilder().setName(indexName).build();
    Index index = SearchServiceFactory.getSearchService().getIndex(indexSpec);
    final int maxRetry = 3;
    int attempts = 0;
    int delay = 2;
    while (true) {
        try {
            index.put(document);
        } catch (PutException e) {
            if (StatusCode.TRANSIENT_ERROR.equals(e.getOperationResult().getCode()) && ++attempts < maxRetry) {
                // retrying
                Thread.sleep(delay * 1000);
                // easy exponential backoff
                delay *= 2;
                continue;
            } else {
                // otherwise throw
                throw e;
            }
        }
        break;
    }
}
Also used : IndexSpec(com.google.appengine.api.search.IndexSpec) PutException(com.google.appengine.api.search.PutException) Index(com.google.appengine.api.search.Index)

Example 3 with PutException

use of com.google.appengine.api.search.PutException in project teammates by TEAMMATES.

the class DataMigrationForFeedbackResponseCommentSearchDocument method invokePutDocumentsWithRetry.

/**
 * Reflects private static method {@link SearchManager#putDocumentsWithRetry}.
 *
 * @throws PutException when only non-transient errors are encountered.
 * @throws MaximumRetriesExceededException with list of failed {@link Document}s as final data and
 *         final {@link com.google.appengine.api.search.OperationResult}'s message as final message,
 *         if operation fails after maximum retries.
 */
private static void invokePutDocumentsWithRetry(String indexName, List<Document> documents) throws PutException, MaximumRetriesExceededException {
    try {
        Method method = SearchManager.class.getDeclaredMethod("putDocumentsWithRetry", String.class, List.class);
        method.setAccessible(true);
        method.invoke(null, indexName, documents);
    } catch (NoSuchMethodException | IllegalAccessException e) {
        throw new RuntimeException(e);
    } catch (InvocationTargetException e) {
        Throwable originalException = e.getCause();
        if (originalException instanceof PutException) {
            throw (PutException) originalException;
        } else if (originalException instanceof MaximumRetriesExceededException) {
            throw (MaximumRetriesExceededException) originalException;
        } else {
            throw new RuntimeException(e);
        }
    }
}
Also used : MaximumRetriesExceededException(teammates.common.util.retry.MaximumRetriesExceededException) PutException(com.google.appengine.api.search.PutException) Method(java.lang.reflect.Method) InvocationTargetException(java.lang.reflect.InvocationTargetException)

Example 4 with PutException

use of com.google.appengine.api.search.PutException in project teammates by TEAMMATES.

the class SearchManager method putDocumentsWithRetry.

/**
 * Tries putting multiple documents, handling transient errors by retrying with exponential backoff.
 *
 * @throws PutException when only non-transient errors are encountered.
 * @throws MaximumRetriesExceededException with list of failed {@link Document}s as final data and
 *         final {@link OperationResult}'s message as final message, if operation fails after maximum retries.
 */
private static void putDocumentsWithRetry(String indexName, final List<Document> documents) throws PutException, MaximumRetriesExceededException {
    final Index index = getIndex(indexName);
    /*
         * The GAE Search API allows batch putting a List of Documents.
         * Results for each document are reported via a List of OperationResults.
         * We use RetryManager to retry putting a List of Documents, with each retry re-putting only
         * the documents that failed in the previous retry.
         * If we encounter one or more transient errors, we retry the operation.
         * If all results are non-transient errors, we give up and throw a PutException upwards.
         */
    RM.runUntilSuccessful(new RetryableTaskThrows<PutException>("Put documents") {

        private List<Document> documentsToPut = documents;

        private List<OperationResult> lastResults;

        private List<String> lastIds;

        @Override
        public void run() throws PutException {
            try {
                PutResponse response = index.put(documentsToPut);
                lastResults = response.getResults();
                lastIds = response.getIds();
            } catch (PutException e) {
                lastResults = e.getResults();
                lastIds = e.getIds();
            }
        }

        @Override
        public boolean isSuccessful() {
            boolean hasTransientError = false;
            List<Document> failedDocuments = new ArrayList<>();
            for (int i = 0; i < documentsToPut.size(); i++) {
                StatusCode code = lastResults.get(i).getCode();
                if (!StatusCode.OK.equals(code)) {
                    failedDocuments.add(documentsToPut.get(i));
                    if (StatusCode.TRANSIENT_ERROR.equals(code)) {
                        hasTransientError = true;
                    }
                }
            }
            // Update the list of documents to be put during the next retry
            documentsToPut = failedDocuments;
            // Update the final message and data to be shown if the task fails after maximum retries
            finalMessage = lastResults.get(0).getMessage();
            finalData = documentsToPut;
            if (documentsToPut.isEmpty()) {
                return true;
            } else if (hasTransientError) {
                // If there is at least one transient error, continue retrying
                return false;
            } else {
                // If all errors are non-transient, do not continue retrying
                throw new PutException(lastResults.get(0), lastResults, lastIds);
            }
        }
    });
}
Also used : Index(com.google.appengine.api.search.Index) OperationResult(com.google.appengine.api.search.OperationResult) Document(com.google.appengine.api.search.Document) ScoredDocument(com.google.appengine.api.search.ScoredDocument) PutResponse(com.google.appengine.api.search.PutResponse) StatusCode(com.google.appengine.api.search.StatusCode) PutException(com.google.appengine.api.search.PutException) ArrayList(java.util.ArrayList) List(java.util.List)

Aggregations

PutException (com.google.appengine.api.search.PutException)4 Index (com.google.appengine.api.search.Index)3 OperationResult (com.google.appengine.api.search.OperationResult)2 PutResponse (com.google.appengine.api.search.PutResponse)2 Document (com.google.appengine.api.search.Document)1 IndexSpec (com.google.appengine.api.search.IndexSpec)1 ScoredDocument (com.google.appengine.api.search.ScoredDocument)1 StatusCode (com.google.appengine.api.search.StatusCode)1 InvocationTargetException (java.lang.reflect.InvocationTargetException)1 Method (java.lang.reflect.Method)1 ArrayList (java.util.ArrayList)1 List (java.util.List)1 MaximumRetriesExceededException (teammates.common.util.retry.MaximumRetriesExceededException)1