Search in sources :

Example 1 with AsynchronousSearchContextPermits

use of org.opensearch.search.asynchronous.context.permits.AsynchronousSearchContextPermits in project asynchronous-search by opensearch-project.

the class AsynchronousSearchService method updateKeepAliveAndGetContext.

/**
 * If an active context is found, a permit is acquired from
 * {@linkplain AsynchronousSearchContextPermits}
 * and on acquisition of permit, a check is performed to see if response has been persisted in system index. If true, we update
 * expiration in index. Else we update expiration field in {@linkplain AsynchronousSearchActiveContext}.
 *
 * @param id                   asynchronous search id
 * @param keepAlive            the new keep alive duration
 * @param asynchronousSearchContextId asynchronous search context id
 * @param user                 current user
 * @param listener             listener to invoke after updating expiration.
 */
public void updateKeepAliveAndGetContext(String id, TimeValue keepAlive, AsynchronousSearchContextId asynchronousSearchContextId, User user, ActionListener<AsynchronousSearchContext> listener) {
    ActionListener<AsynchronousSearchContext> exceptionTranslationWrapper = getExceptionTranslationWrapper(id, listener);
    validateKeepAlive(keepAlive);
    long requestedExpirationTime = currentTimeSupplier.getAsLong() + keepAlive.getMillis();
    // find an active context on this node if one exists
    Optional<AsynchronousSearchActiveContext> asynchronousSearchContextOptional = asynchronousSearchActiveStore.getContext(asynchronousSearchContextId);
    // for all other stages we don't really care much as those contexts are destined to be discarded
    if (asynchronousSearchContextOptional.isPresent()) {
        AsynchronousSearchActiveContext asynchronousSearchActiveContext = asynchronousSearchContextOptional.get();
        asynchronousSearchActiveContext.acquireContextPermitIfRequired(wrap(releasable -> {
            ActionListener<AsynchronousSearchContext> releasableActionListener = runAfter(exceptionTranslationWrapper, releasable::close);
            // At this point it's possible that the response would have been persisted to system index
            if (asynchronousSearchActiveContext.isAlive() == false && asynchronousSearchActiveContext.keepOnCompletion()) {
                logger.debug("Updating persistence store after state is PERSISTED asynchronous search id [{}] " + "for updating context", asynchronousSearchActiveContext.getAsynchronousSearchId());
                persistenceService.updateExpirationTime(id, requestedExpirationTime, user, wrap((actionResponse) -> releasableActionListener.onResponse(new AsynchronousSearchPersistenceContext(id, asynchronousSearchContextId, actionResponse, currentTimeSupplier, namedWriteableRegistry)), releasableActionListener::onFailure));
            } else {
                if (isUserValid(user, asynchronousSearchActiveContext.getUser())) {
                    logger.debug("Updating persistence store: NO as state is NOT PERSISTED yet asynchronous search id [{}] " + "for updating context", asynchronousSearchActiveContext.getAsynchronousSearchId());
                    asynchronousSearchActiveContext.setExpirationTimeMillis(requestedExpirationTime);
                    releasableActionListener.onResponse(asynchronousSearchActiveContext);
                } else {
                    releasableActionListener.onFailure(new OpenSearchSecurityException("User doesn't have necessary roles to access the " + "asynchronous search with id " + id, RestStatus.FORBIDDEN));
                }
            }
        }, exception -> {
            Throwable cause = ExceptionsHelper.unwrapCause(exception);
            if (cause instanceof TimeoutException) {
                // this should ideally not happen. This would mean we couldn't acquire permits within the timeout
                logger.debug(() -> new ParameterizedMessage("Failed to acquire permits for " + "asynchronous search id [{}] for updating context within timeout 5s", asynchronousSearchActiveContext.getAsynchronousSearchId()), exception);
                listener.onFailure(new OpenSearchTimeoutException(id));
            } else {
                // best effort we try an update the doc if one exists
                if (asynchronousSearchActiveContext.keepOnCompletion()) {
                    logger.debug("Updating persistence store after failing to acquire permits for asynchronous search id [{}] for " + "updating context with expiration time [{}]", asynchronousSearchActiveContext.getAsynchronousSearchId(), requestedExpirationTime);
                    persistenceService.updateExpirationTime(id, requestedExpirationTime, user, wrap((actionResponse) -> exceptionTranslationWrapper.onResponse(new AsynchronousSearchPersistenceContext(id, asynchronousSearchContextId, actionResponse, currentTimeSupplier, namedWriteableRegistry)), exceptionTranslationWrapper::onFailure));
                } else {
                    exceptionTranslationWrapper.onFailure(new ResourceNotFoundException(asynchronousSearchActiveContext.getAsynchronousSearchId()));
                }
            }
        }), TimeValue.timeValueSeconds(5), "update keep alive");
    } else {
        // try update the doc on the index assuming there exists one.
        logger.debug("Updating persistence store after active context evicted for asynchronous search id [{}] " + "for updating context", id);
        persistenceService.updateExpirationTime(id, requestedExpirationTime, user, wrap((actionResponse) -> exceptionTranslationWrapper.onResponse(new AsynchronousSearchPersistenceContext(id, asynchronousSearchContextId, actionResponse, currentTimeSupplier, namedWriteableRegistry)), exceptionTranslationWrapper::onFailure));
    }
}
Also used : InternalAsynchronousSearchStats(org.opensearch.search.asynchronous.stats.InternalAsynchronousSearchStats) SearchStartedEvent(org.opensearch.search.asynchronous.context.state.event.SearchStartedEvent) PERSISTING(org.opensearch.search.asynchronous.context.state.AsynchronousSearchState.PERSISTING) LongSupplier(java.util.function.LongSupplier) ActionListener.runAfter(org.opensearch.action.ActionListener.runAfter) AsynchronousSearchState(org.opensearch.search.asynchronous.context.state.AsynchronousSearchState) TimeoutException(java.util.concurrent.TimeoutException) SearchDeletedEvent(org.opensearch.search.asynchronous.context.state.event.SearchDeletedEvent) GroupedActionListener(org.opensearch.action.support.GroupedActionListener) SUCCEEDED(org.opensearch.search.asynchronous.context.state.AsynchronousSearchState.SUCCEEDED) Locale(java.util.Locale) Map(java.util.Map) ActionListener(org.opensearch.action.ActionListener) SearchSuccessfulEvent(org.opensearch.search.asynchronous.context.state.event.SearchSuccessfulEvent) CancelTasksResponse(org.opensearch.action.admin.cluster.node.tasks.cancel.CancelTasksResponse) EnumSet(java.util.EnumSet) AsynchronousSearchTransition(org.opensearch.search.asynchronous.context.state.AsynchronousSearchTransition) AsynchronousSearchContext(org.opensearch.search.asynchronous.context.AsynchronousSearchContext) Client(org.opensearch.client.Client) TimeValue(org.opensearch.common.unit.TimeValue) SearchTask(org.opensearch.action.search.SearchTask) AsynchronousSearchPostProcessor(org.opensearch.search.asynchronous.processor.AsynchronousSearchPostProcessor) ExceptionsHelper(org.opensearch.ExceptionsHelper) Set(java.util.Set) Settings(org.opensearch.common.settings.Settings) SearchResponsePersistedEvent(org.opensearch.search.asynchronous.context.state.event.SearchResponsePersistedEvent) RestStatus(org.opensearch.rest.RestStatus) AsynchronousSearchPersistenceContext(org.opensearch.search.asynchronous.context.persistence.AsynchronousSearchPersistenceContext) Collectors(java.util.stream.Collectors) CLOSED(org.opensearch.search.asynchronous.context.state.AsynchronousSearchState.CLOSED) Objects(java.util.Objects) AbstractLifecycleComponent(org.opensearch.common.component.AbstractLifecycleComponent) RUNNING(org.opensearch.search.asynchronous.context.state.AsynchronousSearchState.RUNNING) Logger(org.apache.logging.log4j.Logger) SubmitAsynchronousSearchRequest(org.opensearch.search.asynchronous.request.SubmitAsynchronousSearchRequest) OpenSearchTimeoutException(org.opensearch.OpenSearchTimeoutException) Optional(java.util.Optional) AsynchronousSearchExceptionUtils(org.opensearch.search.asynchronous.utils.AsynchronousSearchExceptionUtils) ActionListener.wrap(org.opensearch.action.ActionListener.wrap) InternalAggregation(org.opensearch.search.aggregations.InternalAggregation) AsynchronousSearchActiveContext(org.opensearch.search.asynchronous.context.active.AsynchronousSearchActiveContext) AsynchronousSearchContextPermits(org.opensearch.search.asynchronous.context.permits.AsynchronousSearchContextPermits) SearchAction(org.opensearch.action.search.SearchAction) LegacyOpendistroAsynchronousSearchSettings(org.opensearch.search.asynchronous.settings.LegacyOpendistroAsynchronousSearchSettings) PERSIST_SUCCEEDED(org.opensearch.search.asynchronous.context.state.AsynchronousSearchState.PERSIST_SUCCEEDED) ThreadPool(org.opensearch.threadpool.ThreadPool) AsynchronousSearchProgressListener(org.opensearch.search.asynchronous.listener.AsynchronousSearchProgressListener) AsynchronousSearchContextId(org.opensearch.search.asynchronous.context.AsynchronousSearchContextId) AsynchronousSearchPlugin(org.opensearch.search.asynchronous.plugin.AsynchronousSearchPlugin) Releasable(org.opensearch.common.lease.Releasable) ResourceNotFoundException(org.opensearch.ResourceNotFoundException) ClusterStateListener(org.opensearch.cluster.ClusterStateListener) ParameterizedMessage(org.apache.logging.log4j.message.ParameterizedMessage) AtomicReference(java.util.concurrent.atomic.AtomicReference) Supplier(java.util.function.Supplier) UserAuthUtils.isUserValid(org.opensearch.search.asynchronous.utils.UserAuthUtils.isUserValid) NamedWriteableRegistry(org.opensearch.common.io.stream.NamedWriteableRegistry) BeginPersistEvent(org.opensearch.search.asynchronous.context.state.event.BeginPersistEvent) AsynchronousSearchStateMachine(org.opensearch.search.asynchronous.context.state.AsynchronousSearchStateMachine) UUIDs(org.opensearch.common.UUIDs) AsynchronousSearchContextEventListener(org.opensearch.search.asynchronous.listener.AsynchronousSearchContextEventListener) SearchFailureEvent(org.opensearch.search.asynchronous.context.state.event.SearchFailureEvent) AsynchronousSearchStateMachineClosedException(org.opensearch.search.asynchronous.context.state.AsynchronousSearchStateMachineClosedException) Setting(org.opensearch.common.settings.Setting) TaskId(org.opensearch.tasks.TaskId) SearchResponsePersistFailedEvent(org.opensearch.search.asynchronous.context.state.event.SearchResponsePersistFailedEvent) OpenSearchSecurityException(org.opensearch.OpenSearchSecurityException) AtomicLong(java.util.concurrent.atomic.AtomicLong) FAILED(org.opensearch.search.asynchronous.context.state.AsynchronousSearchState.FAILED) INIT(org.opensearch.search.asynchronous.context.state.AsynchronousSearchState.INIT) User(org.opensearch.commons.authuser.User) CancelTasksRequest(org.opensearch.action.admin.cluster.node.tasks.cancel.CancelTasksRequest) ClusterService(org.opensearch.cluster.service.ClusterService) PERSIST_FAILED(org.opensearch.search.asynchronous.context.state.AsynchronousSearchState.PERSIST_FAILED) AsynchronousSearchActiveStore(org.opensearch.search.asynchronous.context.active.AsynchronousSearchActiveStore) AsynchronousSearchStats(org.opensearch.search.asynchronous.stats.AsynchronousSearchStats) LogManager(org.apache.logging.log4j.LogManager) Collections(java.util.Collections) ClusterChangedEvent(org.opensearch.cluster.ClusterChangedEvent) OpenSearchSecurityException(org.opensearch.OpenSearchSecurityException) OpenSearchTimeoutException(org.opensearch.OpenSearchTimeoutException) AsynchronousSearchPersistenceContext(org.opensearch.search.asynchronous.context.persistence.AsynchronousSearchPersistenceContext) AsynchronousSearchContext(org.opensearch.search.asynchronous.context.AsynchronousSearchContext) AsynchronousSearchActiveContext(org.opensearch.search.asynchronous.context.active.AsynchronousSearchActiveContext) GroupedActionListener(org.opensearch.action.support.GroupedActionListener) ActionListener(org.opensearch.action.ActionListener) ParameterizedMessage(org.apache.logging.log4j.message.ParameterizedMessage) ResourceNotFoundException(org.opensearch.ResourceNotFoundException) TimeoutException(java.util.concurrent.TimeoutException) OpenSearchTimeoutException(org.opensearch.OpenSearchTimeoutException)

Aggregations

Collections (java.util.Collections)1 EnumSet (java.util.EnumSet)1 Locale (java.util.Locale)1 Map (java.util.Map)1 Objects (java.util.Objects)1 Optional (java.util.Optional)1 Set (java.util.Set)1 TimeoutException (java.util.concurrent.TimeoutException)1 AtomicLong (java.util.concurrent.atomic.AtomicLong)1 AtomicReference (java.util.concurrent.atomic.AtomicReference)1 LongSupplier (java.util.function.LongSupplier)1 Supplier (java.util.function.Supplier)1 Collectors (java.util.stream.Collectors)1 LogManager (org.apache.logging.log4j.LogManager)1 Logger (org.apache.logging.log4j.Logger)1 ParameterizedMessage (org.apache.logging.log4j.message.ParameterizedMessage)1 ExceptionsHelper (org.opensearch.ExceptionsHelper)1 OpenSearchSecurityException (org.opensearch.OpenSearchSecurityException)1 OpenSearchTimeoutException (org.opensearch.OpenSearchTimeoutException)1 ResourceNotFoundException (org.opensearch.ResourceNotFoundException)1