All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.mongodb.internal.connection.OperationContext Maven / Gradle / Ivy

Go to download

The Java operations layer for the MongoDB Java Driver. Third parties can wrap this layer to provide custom higher-level APIs

The newest version!
/*
 * Copyright 2008-present MongoDB, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.mongodb.internal.connection;

import com.mongodb.MongoConnectionPoolClearedException;
import com.mongodb.RequestContext;
import com.mongodb.ServerAddress;
import com.mongodb.ServerApi;
import com.mongodb.connection.ClusterDescription;
import com.mongodb.connection.ClusterType;
import com.mongodb.connection.ServerDescription;
import com.mongodb.internal.IgnorableRequestContext;
import com.mongodb.internal.TimeoutContext;
import com.mongodb.internal.TimeoutSettings;
import com.mongodb.internal.VisibleForTesting;
import com.mongodb.internal.session.SessionContext;
import com.mongodb.lang.Nullable;
import com.mongodb.selector.ServerSelector;

import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.atomic.AtomicLong;

import static java.util.stream.Collectors.toList;

/**
 * 

This class is not part of the public API and may be removed or changed at any time

*/ public class OperationContext { private static final AtomicLong NEXT_ID = new AtomicLong(0); private final long id; private final ServerDeprioritization serverDeprioritization; private final SessionContext sessionContext; private final RequestContext requestContext; private final TimeoutContext timeoutContext; @Nullable private final ServerApi serverApi; public OperationContext(final RequestContext requestContext, final SessionContext sessionContext, final TimeoutContext timeoutContext, @Nullable final ServerApi serverApi) { this(NEXT_ID.incrementAndGet(), requestContext, sessionContext, timeoutContext, new ServerDeprioritization(), serverApi); } public static OperationContext simpleOperationContext( final TimeoutSettings timeoutSettings, @Nullable final ServerApi serverApi) { return new OperationContext( IgnorableRequestContext.INSTANCE, NoOpSessionContext.INSTANCE, new TimeoutContext(timeoutSettings), serverApi); } public static OperationContext simpleOperationContext(final TimeoutContext timeoutContext) { return new OperationContext( IgnorableRequestContext.INSTANCE, NoOpSessionContext.INSTANCE, timeoutContext, null); } public OperationContext withSessionContext(final SessionContext sessionContext) { return new OperationContext(id, requestContext, sessionContext, timeoutContext, serverDeprioritization, serverApi); } public OperationContext withTimeoutContext(final TimeoutContext timeoutContext) { return new OperationContext(id, requestContext, sessionContext, timeoutContext, serverDeprioritization, serverApi); } public long getId() { return id; } public SessionContext getSessionContext() { return sessionContext; } public RequestContext getRequestContext() { return requestContext; } public TimeoutContext getTimeoutContext() { return timeoutContext; } @Nullable public ServerApi getServerApi() { return serverApi; } @VisibleForTesting(otherwise = VisibleForTesting.AccessModifier.PRIVATE) public OperationContext(final long id, final RequestContext requestContext, final SessionContext sessionContext, final TimeoutContext timeoutContext, final ServerDeprioritization serverDeprioritization, @Nullable final ServerApi serverApi) { this.id = id; this.serverDeprioritization = serverDeprioritization; this.requestContext = requestContext; this.sessionContext = sessionContext; this.timeoutContext = timeoutContext; this.serverApi = serverApi; } @VisibleForTesting(otherwise = VisibleForTesting.AccessModifier.PRIVATE) public OperationContext(final long id, final RequestContext requestContext, final SessionContext sessionContext, final TimeoutContext timeoutContext, @Nullable final ServerApi serverApi) { this.id = id; this.serverDeprioritization = new ServerDeprioritization(); this.requestContext = requestContext; this.sessionContext = sessionContext; this.timeoutContext = timeoutContext; this.serverApi = serverApi; } /** * @return The same {@link ServerDeprioritization} if called on the same {@link OperationContext}. */ public ServerDeprioritization getServerDeprioritization() { return serverDeprioritization; } public static final class ServerDeprioritization { @Nullable private ServerAddress candidate; private final Set deprioritized; private final DeprioritizingSelector selector; private ServerDeprioritization() { candidate = null; deprioritized = new HashSet<>(); selector = new DeprioritizingSelector(); } /** * The returned {@link ServerSelector} tries to {@linkplain ServerSelector#select(ClusterDescription) select} * only the {@link ServerDescription}s that do not have deprioritized {@link ServerAddress}es. * If no such {@link ServerDescription} can be selected, then it selects {@link ClusterDescription#getServerDescriptions()}. */ ServerSelector getServerSelector() { return selector; } void updateCandidate(final ServerAddress serverAddress) { candidate = serverAddress; } public void onAttemptFailure(final Throwable failure) { if (candidate == null || failure instanceof MongoConnectionPoolClearedException) { candidate = null; return; } deprioritized.add(candidate); } /** * {@link ServerSelector} requires thread safety, but that is only because a user may specify * {@link com.mongodb.connection.ClusterSettings.Builder#serverSelector(ServerSelector)}, * which indeed may be used concurrently. {@link DeprioritizingSelector} does not need to be thread-safe. */ private final class DeprioritizingSelector implements ServerSelector { private DeprioritizingSelector() { } @Override public List select(final ClusterDescription clusterDescription) { List serverDescriptions = clusterDescription.getServerDescriptions(); if (!isEnabled(clusterDescription.getType())) { return serverDescriptions; } List nonDeprioritizedServerDescriptions = serverDescriptions .stream() .filter(serverDescription -> !deprioritized.contains(serverDescription.getAddress())) .collect(toList()); return nonDeprioritizedServerDescriptions.isEmpty() ? serverDescriptions : nonDeprioritizedServerDescriptions; } private boolean isEnabled(final ClusterType clusterType) { return clusterType == ClusterType.SHARDED; } } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy