summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Caimano <ben.caimano@mongodb.com>2019-09-09 18:45:01 +0000
committerevergreen <evergreen@mongodb.com>2019-09-09 18:45:01 +0000
commit0f16c5fc452d16c5a92e43e9fdd96f3822f05271 (patch)
tree890ff8a80ae78d7831452aedb30feb9e76be1567
parentf4e387fa1b7e369ce067650bdda9c8676683b929 (diff)
downloadmongo-0f16c5fc452d16c5a92e43e9fdd96f3822f05271.tar.gz
SERVER-42908 Add ErrorCodes to retryable errors to match drivers
-rw-r--r--src/mongo/base/error_codes.yml625
-rw-r--r--src/mongo/client/fetcher_test.cpp10
-rw-r--r--src/mongo/client/remote_command_retry_scheduler.cpp89
-rw-r--r--src/mongo/client/remote_command_retry_scheduler.h90
-rw-r--r--src/mongo/client/remote_command_retry_scheduler_test.cpp49
-rw-r--r--src/mongo/db/repl/collection_cloner.cpp10
-rw-r--r--src/mongo/db/repl/database_cloner.cpp32
-rw-r--r--src/mongo/db/repl/databases_cloner.cpp5
-rw-r--r--src/mongo/db/repl/initial_syncer.cpp36
-rw-r--r--src/mongo/s/client/shard.cpp6
-rw-r--r--src/mongo/s/client/shard_remote.cpp19
-rw-r--r--src/mongo/s/query/establish_cursors.cpp8
-rw-r--r--src/mongo/s/transaction_router.cpp11
-rw-r--r--src/mongo/util/assert_util_test.cpp14
14 files changed, 478 insertions, 526 deletions
diff --git a/src/mongo/base/error_codes.yml b/src/mongo/base/error_codes.yml
index 154eda988c0..fec5207822c 100644
--- a/src/mongo/base/error_codes.yml
+++ b/src/mongo/base/error_codes.yml
@@ -1,17 +1,17 @@
-# Group related errors into categories, can be checked against ErrorCodes::isXXXClassName methods.
+# Group related errors into categories,can be checked against ErrorCodes::isXXXClassName methods.
error_categories:
- NetworkError
- Interruption
# isNotMasterError() includes all codes that indicate that the node that received the request
- # was not master at some point during command processing, regardless of whether some write may
- # have happened. If you care about whether a write could have happened, check for individual
+ # was not master at some point during command processing,regardless of whether some write may
+ # have happened. If you care about whether a write could have happened,check for individual
# codes.
- NotMasterError
- StaleShardVersionError
- NeedRetargettingError
- WriteConcernError
- ShutdownError
- # isCancelationError() includes all codes that, when passed to a function as its parameter
+ # isCancelationError() includes all codes that,when passed to a function as its parameter
# indicates that it cannot be executed as normal and must abort its intended work.
- CancelationError
- ConnectionFatalMessageParseError
@@ -19,333 +19,334 @@ error_categories:
- SnapshotError
- VoteAbortError
- NonResumableChangeStreamError
+ - RetriableError
error_codes:
- - {code: 0, name: OK}
- - {code: 1, name: InternalError}
- - {code: 2, name: BadValue}
- - {code: 3, name: OBSOLETE_DuplicateKey}
- - {code: 4, name: NoSuchKey}
- - {code: 5, name: GraphContainsCycle}
- - {code: 6, name: HostUnreachable, categories: [NetworkError]}
- - {code: 7, name: HostNotFound, categories: [NetworkError]}
- - {code: 8, name: UnknownError}
- - {code: 9, name: FailedToParse}
- - {code: 10, name: CannotMutateObject}
- - {code: 11, name: UserNotFound}
- - {code: 12, name: UnsupportedFormat}
- - {code: 13, name: Unauthorized}
- - {code: 14, name: TypeMismatch}
- - {code: 15, name: Overflow}
- - {code: 16, name: InvalidLength}
- - {code: 17, name: ProtocolError}
- - {code: 18, name: AuthenticationFailed}
- - {code: 19, name: CannotReuseObject}
- - {code: 20, name: IllegalOperation}
- - {code: 21, name: EmptyArrayOperation}
- - {code: 22, name: InvalidBSON}
- - {code: 23, name: AlreadyInitialized}
- - {code: 24, name: LockTimeout, categories: [Interruption]}
- - {code: 25, name: RemoteValidationError}
- - {code: 26, name: NamespaceNotFound}
- - {code: 27, name: IndexNotFound}
- - {code: 28, name: PathNotViable}
- - {code: 29, name: NonExistentPath}
- - {code: 30, name: InvalidPath}
- - {code: 31, name: RoleNotFound}
- - {code: 32, name: RolesNotRelated}
- - {code: 33, name: PrivilegeNotFound}
- - {code: 34, name: CannotBackfillArray}
- - {code: 35, name: UserModificationFailed}
- - {code: 36, name: RemoteChangeDetected}
- - {code: 37, name: FileRenameFailed}
- - {code: 38, name: FileNotOpen}
- - {code: 39, name: FileStreamFailed}
- - {code: 40, name: ConflictingUpdateOperators}
- - {code: 41, name: FileAlreadyOpen}
- - {code: 42, name: LogWriteFailed}
- - {code: 43, name: CursorNotFound}
- - {code: 45, name: UserDataInconsistent}
- - {code: 46, name: LockBusy}
- - {code: 47, name: NoMatchingDocument}
- - {code: 48, name: NamespaceExists}
- - {code: 49, name: InvalidRoleModification}
- - {code: 50, name: MaxTimeMSExpired, categories: [Interruption,ExceededTimeLimitError]}
- - {code: 51, name: ManualInterventionRequired}
- - {code: 52, name: DollarPrefixedFieldName}
- - {code: 53, name: InvalidIdField}
- - {code: 54, name: NotSingleValueField}
- - {code: 55, name: InvalidDBRef}
- - {code: 56, name: EmptyFieldName}
- - {code: 57, name: DottedFieldName}
- - {code: 58, name: RoleModificationFailed}
- - {code: 59, name: CommandNotFound}
- - {code: 60, name: OBSOLETE_DatabaseNotFound}
- - {code: 61, name: ShardKeyNotFound}
- - {code: 62, name: OplogOperationUnsupported}
- - {code: 63, name: StaleShardVersion, categories: [StaleShardVersionError,NeedRetargettingError]}
- - {code: 64, name: WriteConcernFailed, categories: [WriteConcernError]}
- - {code: 65, name: MultipleErrorsOccurred}
- - {code: 66, name: ImmutableField}
- - {code: 67, name: CannotCreateIndex}
- - {code: 68, name: IndexAlreadyExists}
- - {code: 69, name: AuthSchemaIncompatible}
- - {code: 70, name: ShardNotFound}
- - {code: 71, name: ReplicaSetNotFound}
- - {code: 72, name: InvalidOptions}
- - {code: 73, name: InvalidNamespace}
- - {code: 74, name: NodeNotFound}
- - {code: 75, name: WriteConcernLegacyOK, categories: [WriteConcernError]}
- - {code: 76, name: NoReplicationEnabled}
- - {code: 77, name: OperationIncomplete}
- - {code: 78, name: CommandResultSchemaViolation}
- - {code: 79, name: UnknownReplWriteConcern, categories: [WriteConcernError]}
- - {code: 80, name: RoleDataInconsistent}
- - {code: 81, name: NoMatchParseContext}
- - {code: 82, name: NoProgressMade}
- - {code: 83, name: RemoteResultsUnavailable}
- - {code: 84, name: DuplicateKeyValue}
- - {code: 85, name: IndexOptionsConflict}
- - {code: 86, name: IndexKeySpecsConflict}
- - {code: 87, name: CannotSplit}
- - {code: 88, name: SplitFailed_OBSOLETE}
- - {code: 89, name: NetworkTimeout, categories: [NetworkError]}
- - {code: 90, name: CallbackCanceled, categories: [CancelationError]}
- - {code: 91, name: ShutdownInProgress, categories: [ShutdownError, CancelationError]}
- - {code: 92, name: SecondaryAheadOfPrimary}
- - {code: 93, name: InvalidReplicaSetConfig}
- - {code: 94, name: NotYetInitialized}
- - {code: 95, name: NotSecondary}
- - {code: 96, name: OperationFailed}
- - {code: 97, name: NoProjectionFound}
- - {code: 98, name: DBPathInUse}
- - {code: 100, name: UnsatisfiableWriteConcern, categories: [WriteConcernError]}
- - {code: 101, name: OutdatedClient}
- - {code: 102, name: IncompatibleAuditMetadata}
- - {code: 103, name: NewReplicaSetConfigurationIncompatible}
- - {code: 104, name: NodeNotElectable}
- - {code: 105, name: IncompatibleShardingMetadata}
- - {code: 106, name: DistributedClockSkewed}
- - {code: 107, name: LockFailed}
- - {code: 108, name: InconsistentReplicaSetNames}
- - {code: 109, name: ConfigurationInProgress}
- - {code: 110, name: CannotInitializeNodeWithData}
- - {code: 111, name: NotExactValueField}
- - {code: 112, name: WriteConflict}
- - {code: 113, name: InitialSyncFailure}
- - {code: 114, name: InitialSyncOplogSourceMissing}
- - {code: 115, name: CommandNotSupported}
- - {code: 116, name: DocTooLargeForCapped}
- - {code: 117, name: ConflictingOperationInProgress}
- - {code: 118, name: NamespaceNotSharded}
- - {code: 119, name: InvalidSyncSource}
- - {code: 120, name: OplogStartMissing}
- - {code: 121, name: DocumentValidationFailure} # Only for the document validator on collections.
- - {code: 122, name: OBSOLETE_ReadAfterOptimeTimeout}
- - {code: 123, name: NotAReplicaSet}
- - {code: 124, name: IncompatibleElectionProtocol}
- - {code: 125, name: CommandFailed}
- - {code: 126, name: RPCProtocolNegotiationFailed}
- - {code: 127, name: UnrecoverableRollbackError}
- - {code: 128, name: LockNotFound}
- - {code: 129, name: LockStateChangeFailed}
- - {code: 130, name: SymbolNotFound}
- #- {code: 131, name: RLPInitializationFailed} # Removed in 4.2
- - {code: 132, name: OBSOLETE_ConfigServersInconsistent}
- - {code: 133, name: FailedToSatisfyReadPreference}
- - {code: 134, name: ReadConcernMajorityNotAvailableYet}
- - {code: 135, name: StaleTerm}
- - {code: 136, name: CappedPositionLost}
- - {code: 137, name: IncompatibleShardingConfigVersion}
- - {code: 138, name: RemoteOplogStale}
- - {code: 139, name: JSInterpreterFailure}
- - {code: 140, name: InvalidSSLConfiguration}
- - {code: 141, name: SSLHandshakeFailed}
- - {code: 142, name: JSUncatchableError}
- - {code: 143, name: CursorInUse}
- - {code: 144, name: IncompatibleCatalogManager}
- - {code: 145, name: PooledConnectionsDropped}
- - {code: 146, name: ExceededMemoryLimit}
- - {code: 147, name: ZLibError}
- - {code: 148, name: ReadConcernMajorityNotEnabled, categories: [VoteAbortError]}
- - {code: 149, name: NoConfigMaster}
- - {code: 150, name: StaleEpoch, categories: [StaleShardVersionError,NeedRetargettingError]}
- - {code: 151, name: OperationCannotBeBatched}
- - {code: 152, name: OplogOutOfOrder}
- - {code: 153, name: ChunkTooBig}
- - {code: 154, name: InconsistentShardIdentity}
- - {code: 155, name: CannotApplyOplogWhilePrimary}
- - {code: 156, name: OBSOLETE_NeedsDocumentMove}
- - {code: 157, name: CanRepairToDowngrade}
- - {code: 158, name: MustUpgrade}
- - {code: 159, name: DurationOverflow}
- - {code: 160, name: MaxStalenessOutOfRange}
- - {code: 161, name: IncompatibleCollationVersion}
- - {code: 162, name: CollectionIsEmpty}
- - {code: 163, name: ZoneStillInUse}
- - {code: 164, name: InitialSyncActive}
- - {code: 165, name: ViewDepthLimitExceeded}
- - {code: 166, name: CommandNotSupportedOnView}
- - {code: 167, name: OptionNotSupportedOnView}
- - {code: 168, name: InvalidPipelineOperator}
- - {code: 169, name: CommandOnShardedViewNotSupportedOnMongod, extra: ResolvedView}
- - {code: 170, name: TooManyMatchingDocuments}
- - {code: 171, name: CannotIndexParallelArrays}
- - {code: 172, name: TransportSessionClosed}
- - {code: 173, name: TransportSessionNotFound}
- - {code: 174, name: TransportSessionUnknown}
- - {code: 175, name: QueryPlanKilled}
- - {code: 176, name: FileOpenFailed}
- - {code: 177, name: ZoneNotFound}
- - {code: 178, name: RangeOverlapConflict}
- - {code: 179, name: WindowsPdhError}
- - {code: 180, name: BadPerfCounterPath}
- - {code: 181, name: AmbiguousIndexKeyPattern}
- - {code: 182, name: InvalidViewDefinition}
- - {code: 183, name: ClientMetadataMissingField}
- - {code: 184, name: ClientMetadataAppNameTooLarge}
- - {code: 185, name: ClientMetadataDocumentTooLarge}
- - {code: 186, name: ClientMetadataCannotBeMutated}
- - {code: 187, name: LinearizableReadConcernError}
- - {code: 188, name: IncompatibleServerVersion}
- - {code: 189, name: PrimarySteppedDown, categories: [NotMasterError]}
- - {code: 190, name: MasterSlaveConnectionFailure}
- - {code: 191, name: OBSOLETE_BalancerLostDistributedLock}
- - {code: 192, name: FailPointEnabled}
- - {code: 193, name: NoShardingEnabled}
- - {code: 194, name: BalancerInterrupted}
- - {code: 195, name: ViewPipelineMaxSizeExceeded}
- - {code: 197, name: InvalidIndexSpecificationOption}
- - {code: 198, name: OBSOLETE_ReceivedOpReplyMessage}
- - {code: 199, name: ReplicaSetMonitorRemoved}
- - {code: 200, name: ChunkRangeCleanupPending}
- - {code: 201, name: CannotBuildIndexKeys}
- - {code: 202, name: NetworkInterfaceExceededTimeLimit, categories: [ExceededTimeLimitError]}
- - {code: 203, name: ShardingStateNotInitialized}
- - {code: 204, name: TimeProofMismatch}
- - {code: 205, name: ClusterTimeFailsRateLimiter}
- - {code: 206, name: NoSuchSession}
- - {code: 207, name: InvalidUUID}
- - {code: 208, name: TooManyLocks}
- - {code: 209, name: StaleClusterTime}
- - {code: 210, name: CannotVerifyAndSignLogicalTime}
- - {code: 211, name: KeyNotFound}
- - {code: 212, name: IncompatibleRollbackAlgorithm}
- - {code: 213, name: DuplicateSession}
- - {code: 214, name: AuthenticationRestrictionUnmet}
- - {code: 215, name: DatabaseDropPending}
- - {code: 216, name: ElectionInProgress}
- - {code: 217, name: IncompleteTransactionHistory}
- - {code: 218, name: UpdateOperationFailed}
- - {code: 219, name: FTDCPathNotSet}
- - {code: 220, name: FTDCPathAlreadySet}
- - {code: 221, name: IndexModified}
- - {code: 222, name: CloseChangeStream}
- - {code: 223, name: IllegalOpMsgFlag, categories: [ConnectionFatalMessageParseError]}
- - {code: 224, name: QueryFeatureNotAllowed}
- - {code: 225, name: TransactionTooOld, categories: [VoteAbortError]}
- - {code: 226, name: AtomicityFailure}
- - {code: 227, name: CannotImplicitlyCreateCollection,
+ - {code: 0,name: OK}
+ - {code: 1,name: InternalError}
+ - {code: 2,name: BadValue}
+ - {code: 3,name: OBSOLETE_DuplicateKey}
+ - {code: 4,name: NoSuchKey}
+ - {code: 5,name: GraphContainsCycle}
+ - {code: 6,name: HostUnreachable,categories: [NetworkError,RetriableError]}
+ - {code: 7,name: HostNotFound,categories: [NetworkError,RetriableError]}
+ - {code: 8,name: UnknownError}
+ - {code: 9,name: FailedToParse}
+ - {code: 10,name: CannotMutateObject}
+ - {code: 11,name: UserNotFound}
+ - {code: 12,name: UnsupportedFormat}
+ - {code: 13,name: Unauthorized}
+ - {code: 14,name: TypeMismatch}
+ - {code: 15,name: Overflow}
+ - {code: 16,name: InvalidLength}
+ - {code: 17,name: ProtocolError}
+ - {code: 18,name: AuthenticationFailed}
+ - {code: 19,name: CannotReuseObject}
+ - {code: 20,name: IllegalOperation}
+ - {code: 21,name: EmptyArrayOperation}
+ - {code: 22,name: InvalidBSON}
+ - {code: 23,name: AlreadyInitialized}
+ - {code: 24,name: LockTimeout,categories: [Interruption]}
+ - {code: 25,name: RemoteValidationError}
+ - {code: 26,name: NamespaceNotFound}
+ - {code: 27,name: IndexNotFound}
+ - {code: 28,name: PathNotViable}
+ - {code: 29,name: NonExistentPath}
+ - {code: 30,name: InvalidPath}
+ - {code: 31,name: RoleNotFound}
+ - {code: 32,name: RolesNotRelated}
+ - {code: 33,name: PrivilegeNotFound}
+ - {code: 34,name: CannotBackfillArray}
+ - {code: 35,name: UserModificationFailed}
+ - {code: 36,name: RemoteChangeDetected}
+ - {code: 37,name: FileRenameFailed}
+ - {code: 38,name: FileNotOpen}
+ - {code: 39,name: FileStreamFailed}
+ - {code: 40,name: ConflictingUpdateOperators}
+ - {code: 41,name: FileAlreadyOpen}
+ - {code: 42,name: LogWriteFailed}
+ - {code: 43,name: CursorNotFound}
+ - {code: 45,name: UserDataInconsistent}
+ - {code: 46,name: LockBusy}
+ - {code: 47,name: NoMatchingDocument}
+ - {code: 48,name: NamespaceExists}
+ - {code: 49,name: InvalidRoleModification}
+ - {code: 50,name: MaxTimeMSExpired,categories: [Interruption,ExceededTimeLimitError]}
+ - {code: 51,name: ManualInterventionRequired}
+ - {code: 52,name: DollarPrefixedFieldName}
+ - {code: 53,name: InvalidIdField}
+ - {code: 54,name: NotSingleValueField}
+ - {code: 55,name: InvalidDBRef}
+ - {code: 56,name: EmptyFieldName}
+ - {code: 57,name: DottedFieldName}
+ - {code: 58,name: RoleModificationFailed}
+ - {code: 59,name: CommandNotFound}
+ - {code: 60,name: OBSOLETE_DatabaseNotFound}
+ - {code: 61,name: ShardKeyNotFound}
+ - {code: 62,name: OplogOperationUnsupported}
+ - {code: 63,name: StaleShardVersion,categories: [StaleShardVersionError,NeedRetargettingError]}
+ - {code: 64,name: WriteConcernFailed,categories: [WriteConcernError,RetriableError]}
+ - {code: 65,name: MultipleErrorsOccurred}
+ - {code: 66,name: ImmutableField}
+ - {code: 67,name: CannotCreateIndex}
+ - {code: 68,name: IndexAlreadyExists}
+ - {code: 69,name: AuthSchemaIncompatible}
+ - {code: 70,name: ShardNotFound}
+ - {code: 71,name: ReplicaSetNotFound}
+ - {code: 72,name: InvalidOptions}
+ - {code: 73,name: InvalidNamespace}
+ - {code: 74,name: NodeNotFound}
+ - {code: 75,name: WriteConcernLegacyOK,categories: [WriteConcernError]}
+ - {code: 76,name: NoReplicationEnabled}
+ - {code: 77,name: OperationIncomplete}
+ - {code: 78,name: CommandResultSchemaViolation}
+ - {code: 79,name: UnknownReplWriteConcern,categories: [WriteConcernError]}
+ - {code: 80,name: RoleDataInconsistent}
+ - {code: 81,name: NoMatchParseContext}
+ - {code: 82,name: NoProgressMade}
+ - {code: 83,name: RemoteResultsUnavailable}
+ - {code: 84,name: DuplicateKeyValue}
+ - {code: 85,name: IndexOptionsConflict}
+ - {code: 86,name: IndexKeySpecsConflict}
+ - {code: 87,name: CannotSplit}
+ - {code: 88,name: SplitFailed_OBSOLETE}
+ - {code: 89,name: NetworkTimeout,categories: [NetworkError,RetriableError]}
+ - {code: 90,name: CallbackCanceled,categories: [CancelationError]}
+ - {code: 91,name: ShutdownInProgress,categories: [ShutdownError,CancelationError,RetriableError]}
+ - {code: 92,name: SecondaryAheadOfPrimary}
+ - {code: 93,name: InvalidReplicaSetConfig}
+ - {code: 94,name: NotYetInitialized}
+ - {code: 95,name: NotSecondary}
+ - {code: 96,name: OperationFailed}
+ - {code: 97,name: NoProjectionFound}
+ - {code: 98,name: DBPathInUse}
+ - {code: 100,name: UnsatisfiableWriteConcern,categories: [WriteConcernError]}
+ - {code: 101,name: OutdatedClient}
+ - {code: 102,name: IncompatibleAuditMetadata}
+ - {code: 103,name: NewReplicaSetConfigurationIncompatible}
+ - {code: 104,name: NodeNotElectable}
+ - {code: 105,name: IncompatibleShardingMetadata}
+ - {code: 106,name: DistributedClockSkewed}
+ - {code: 107,name: LockFailed}
+ - {code: 108,name: InconsistentReplicaSetNames}
+ - {code: 109,name: ConfigurationInProgress}
+ - {code: 110,name: CannotInitializeNodeWithData}
+ - {code: 111,name: NotExactValueField}
+ - {code: 112,name: WriteConflict}
+ - {code: 113,name: InitialSyncFailure}
+ - {code: 114,name: InitialSyncOplogSourceMissing}
+ - {code: 115,name: CommandNotSupported}
+ - {code: 116,name: DocTooLargeForCapped}
+ - {code: 117,name: ConflictingOperationInProgress}
+ - {code: 118,name: NamespaceNotSharded}
+ - {code: 119,name: InvalidSyncSource}
+ - {code: 120,name: OplogStartMissing}
+ - {code: 121,name: DocumentValidationFailure} # Only for the document validator on collections.
+ - {code: 122,name: OBSOLETE_ReadAfterOptimeTimeout}
+ - {code: 123,name: NotAReplicaSet}
+ - {code: 124,name: IncompatibleElectionProtocol}
+ - {code: 125,name: CommandFailed}
+ - {code: 126,name: RPCProtocolNegotiationFailed}
+ - {code: 127,name: UnrecoverableRollbackError}
+ - {code: 128,name: LockNotFound}
+ - {code: 129,name: LockStateChangeFailed}
+ - {code: 130,name: SymbolNotFound}
+ #- {code: 131,name: RLPInitializationFailed} # Removed in 4.2
+ - {code: 132,name: OBSOLETE_ConfigServersInconsistent}
+ - {code: 133,name: FailedToSatisfyReadPreference}
+ - {code: 134,name: ReadConcernMajorityNotAvailableYet}
+ - {code: 135,name: StaleTerm}
+ - {code: 136,name: CappedPositionLost}
+ - {code: 137,name: IncompatibleShardingConfigVersion}
+ - {code: 138,name: RemoteOplogStale}
+ - {code: 139,name: JSInterpreterFailure}
+ - {code: 140,name: InvalidSSLConfiguration}
+ - {code: 141,name: SSLHandshakeFailed}
+ - {code: 142,name: JSUncatchableError}
+ - {code: 143,name: CursorInUse}
+ - {code: 144,name: IncompatibleCatalogManager}
+ - {code: 145,name: PooledConnectionsDropped}
+ - {code: 146,name: ExceededMemoryLimit}
+ - {code: 147,name: ZLibError}
+ - {code: 148,name: ReadConcernMajorityNotEnabled,categories: [VoteAbortError]}
+ - {code: 149,name: NoConfigMaster}
+ - {code: 150,name: StaleEpoch,categories: [StaleShardVersionError,NeedRetargettingError]}
+ - {code: 151,name: OperationCannotBeBatched}
+ - {code: 152,name: OplogOutOfOrder}
+ - {code: 153,name: ChunkTooBig}
+ - {code: 154,name: InconsistentShardIdentity}
+ - {code: 155,name: CannotApplyOplogWhilePrimary}
+ - {code: 156,name: OBSOLETE_NeedsDocumentMove}
+ - {code: 157,name: CanRepairToDowngrade}
+ - {code: 158,name: MustUpgrade}
+ - {code: 159,name: DurationOverflow}
+ - {code: 160,name: MaxStalenessOutOfRange}
+ - {code: 161,name: IncompatibleCollationVersion}
+ - {code: 162,name: CollectionIsEmpty}
+ - {code: 163,name: ZoneStillInUse}
+ - {code: 164,name: InitialSyncActive}
+ - {code: 165,name: ViewDepthLimitExceeded}
+ - {code: 166,name: CommandNotSupportedOnView}
+ - {code: 167,name: OptionNotSupportedOnView}
+ - {code: 168,name: InvalidPipelineOperator}
+ - {code: 169,name: CommandOnShardedViewNotSupportedOnMongod,extra: ResolvedView}
+ - {code: 170,name: TooManyMatchingDocuments}
+ - {code: 171,name: CannotIndexParallelArrays}
+ - {code: 172,name: TransportSessionClosed}
+ - {code: 173,name: TransportSessionNotFound}
+ - {code: 174,name: TransportSessionUnknown}
+ - {code: 175,name: QueryPlanKilled}
+ - {code: 176,name: FileOpenFailed}
+ - {code: 177,name: ZoneNotFound}
+ - {code: 178,name: RangeOverlapConflict}
+ - {code: 179,name: WindowsPdhError}
+ - {code: 180,name: BadPerfCounterPath}
+ - {code: 181,name: AmbiguousIndexKeyPattern}
+ - {code: 182,name: InvalidViewDefinition}
+ - {code: 183,name: ClientMetadataMissingField}
+ - {code: 184,name: ClientMetadataAppNameTooLarge}
+ - {code: 185,name: ClientMetadataDocumentTooLarge}
+ - {code: 186,name: ClientMetadataCannotBeMutated}
+ - {code: 187,name: LinearizableReadConcernError}
+ - {code: 188,name: IncompatibleServerVersion}
+ - {code: 189,name: PrimarySteppedDown,categories: [NotMasterError,RetriableError]}
+ - {code: 190,name: MasterSlaveConnectionFailure}
+ - {code: 191,name: OBSOLETE_BalancerLostDistributedLock}
+ - {code: 192,name: FailPointEnabled}
+ - {code: 193,name: NoShardingEnabled}
+ - {code: 194,name: BalancerInterrupted,categories: [RetriableError]}
+ - {code: 195,name: ViewPipelineMaxSizeExceeded}
+ - {code: 197,name: InvalidIndexSpecificationOption}
+ - {code: 198,name: OBSOLETE_ReceivedOpReplyMessage}
+ - {code: 199,name: ReplicaSetMonitorRemoved}
+ - {code: 200,name: ChunkRangeCleanupPending}
+ - {code: 201,name: CannotBuildIndexKeys}
+ - {code: 202,name: NetworkInterfaceExceededTimeLimit,categories: [ExceededTimeLimitError]}
+ - {code: 203,name: ShardingStateNotInitialized}
+ - {code: 204,name: TimeProofMismatch}
+ - {code: 205,name: ClusterTimeFailsRateLimiter}
+ - {code: 206,name: NoSuchSession}
+ - {code: 207,name: InvalidUUID}
+ - {code: 208,name: TooManyLocks}
+ - {code: 209,name: StaleClusterTime}
+ - {code: 210,name: CannotVerifyAndSignLogicalTime}
+ - {code: 211,name: KeyNotFound}
+ - {code: 212,name: IncompatibleRollbackAlgorithm}
+ - {code: 213,name: DuplicateSession}
+ - {code: 214,name: AuthenticationRestrictionUnmet}
+ - {code: 215,name: DatabaseDropPending}
+ - {code: 216,name: ElectionInProgress}
+ - {code: 217,name: IncompleteTransactionHistory}
+ - {code: 218,name: UpdateOperationFailed}
+ - {code: 219,name: FTDCPathNotSet}
+ - {code: 220,name: FTDCPathAlreadySet}
+ - {code: 221,name: IndexModified}
+ - {code: 222,name: CloseChangeStream}
+ - {code: 223,name: IllegalOpMsgFlag,categories: [ConnectionFatalMessageParseError]}
+ - {code: 224,name: QueryFeatureNotAllowed}
+ - {code: 225,name: TransactionTooOld,categories: [VoteAbortError]}
+ - {code: 226,name: AtomicityFailure}
+ - {code: 227,name: CannotImplicitlyCreateCollection,
extra: CannotImplicitlyCreateCollectionInfo,
categories: [NeedRetargettingError]}
- - {code: 228, name: SessionTransferIncomplete}
- - {code: 229, name: MustDowngrade}
- - {code: 230, name: DNSHostNotFound}
- - {code: 231, name: DNSProtocolError}
- - {code: 232, name: MaxSubPipelineDepthExceeded}
- - {code: 233, name: TooManyDocumentSequences, categories: [ConnectionFatalMessageParseError]}
- - {code: 234, name: RetryChangeStream}
+ - {code: 228,name: SessionTransferIncomplete}
+ - {code: 229,name: MustDowngrade}
+ - {code: 230,name: DNSHostNotFound}
+ - {code: 231,name: DNSProtocolError}
+ - {code: 232,name: MaxSubPipelineDepthExceeded}
+ - {code: 233,name: TooManyDocumentSequences,categories: [ConnectionFatalMessageParseError]}
+ - {code: 234,name: RetryChangeStream}
# this function or module is not available on this platform or configuration
- - {code: 235, name: InternalErrorNotSupported}
+ - {code: 235,name: InternalErrorNotSupported}
- - {code: 236, name: ForTestingErrorExtraInfo, extra: ErrorExtraInfoExample}
- - {code: 237, name: CursorKilled, categories: [Interruption]}
- - {code: 238, name: NotImplemented}
- - {code: 239, name: SnapshotTooOld, categories: [SnapshotError]}
- - {code: 240, name: DNSRecordTypeMismatch}
- - {code: 241, name: ConversionFailure}
- - {code: 242, name: CannotCreateCollection}
- - {code: 243, name: IncompatibleWithUpgradedServer}
- - {code: 244, name: NOT_YET_AVAILABLE_TransactionAborted}
- - {code: 245, name: BrokenPromise}
- - {code: 246, name: SnapshotUnavailable, categories: [SnapshotError]}
- - {code: 247, name: ProducerConsumerQueueBatchTooLarge}
- - {code: 248, name: ProducerConsumerQueueEndClosed}
- - {code: 249, name: StaleDbVersion, extra: StaleDbRoutingVersion}
- - {code: 250, name: StaleChunkHistory, categories: [SnapshotError]}
- - {code: 251, name: NoSuchTransaction, categories: [VoteAbortError]}
- - {code: 252, name: ReentrancyNotAllowed}
- - {code: 253, name: FreeMonHttpInFlight}
- - {code: 254, name: FreeMonHttpTemporaryFailure}
- - {code: 255, name: FreeMonHttpPermanentFailure}
- - {code: 256, name: TransactionCommitted}
- - {code: 257, name: TransactionTooLarge}
- - {code: 258, name: UnknownFeatureCompatibilityVersion}
- - {code: 259, name: KeyedExecutorRetry}
- - {code: 260, name: InvalidResumeToken}
- - {code: 261, name: TooManyLogicalSessions}
- - {code: 262, name: ExceededTimeLimit, categories: [Interruption,ExceededTimeLimitError]}
- - {code: 263, name: OperationNotSupportedInTransaction}
- - {code: 264, name: TooManyFilesOpen}
- - {code: 265, name: OrphanedRangeCleanUpFailed}
- - {code: 266, name: FailPointSetFailed}
- - {code: 267, name: PreparedTransactionInProgress}
- - {code: 268, name: CannotBackup}
- - {code: 269, name: DataModifiedByRepair}
- - {code: 270, name: RepairedReplicaSetNode}
- - {code: 271, name: JSInterpreterFailureWithStack, extra: JSExceptionInfo}
- - {code: 272, name: MigrationConflict, categories: [SnapshotError]}
- - {code: 273, name: ProducerConsumerQueueProducerQueueDepthExceeded}
- - {code: 274, name: ProducerConsumerQueueConsumed}
- - {code: 275, name: ExchangePassthrough} # For exchange execution in aggregation. Do not reuse.
- - {code: 276, name: IndexBuildAborted}
- - {code: 277, name: AlarmAlreadyFulfilled}
- - {code: 278, name: UnsatisfiableCommitQuorum}
- - {code: 279, name: ClientDisconnect, categories: [Interruption]}
- - {code: 280, name: ChangeStreamFatalError, categories: [NonResumableChangeStreamError]}
+ - {code: 236,name: ForTestingErrorExtraInfo,extra: ErrorExtraInfoExample}
+ - {code: 237,name: CursorKilled,categories: [Interruption]}
+ - {code: 238,name: NotImplemented}
+ - {code: 239,name: SnapshotTooOld,categories: [SnapshotError]}
+ - {code: 240,name: DNSRecordTypeMismatch}
+ - {code: 241,name: ConversionFailure}
+ - {code: 242,name: CannotCreateCollection}
+ - {code: 243,name: IncompatibleWithUpgradedServer}
+ - {code: 244,name: NOT_YET_AVAILABLE_TransactionAborted}
+ - {code: 245,name: BrokenPromise}
+ - {code: 246,name: SnapshotUnavailable,categories: [SnapshotError]}
+ - {code: 247,name: ProducerConsumerQueueBatchTooLarge}
+ - {code: 248,name: ProducerConsumerQueueEndClosed}
+ - {code: 249,name: StaleDbVersion,extra: StaleDbRoutingVersion}
+ - {code: 250,name: StaleChunkHistory,categories: [SnapshotError]}
+ - {code: 251,name: NoSuchTransaction,categories: [VoteAbortError]}
+ - {code: 252,name: ReentrancyNotAllowed}
+ - {code: 253,name: FreeMonHttpInFlight}
+ - {code: 254,name: FreeMonHttpTemporaryFailure}
+ - {code: 255,name: FreeMonHttpPermanentFailure}
+ - {code: 256,name: TransactionCommitted}
+ - {code: 257,name: TransactionTooLarge}
+ - {code: 258,name: UnknownFeatureCompatibilityVersion}
+ - {code: 259,name: KeyedExecutorRetry}
+ - {code: 260,name: InvalidResumeToken}
+ - {code: 261,name: TooManyLogicalSessions}
+ - {code: 262,name: ExceededTimeLimit,categories: [Interruption,ExceededTimeLimitError]}
+ - {code: 263,name: OperationNotSupportedInTransaction}
+ - {code: 264,name: TooManyFilesOpen}
+ - {code: 265,name: OrphanedRangeCleanUpFailed}
+ - {code: 266,name: FailPointSetFailed}
+ - {code: 267,name: PreparedTransactionInProgress}
+ - {code: 268,name: CannotBackup}
+ - {code: 269,name: DataModifiedByRepair}
+ - {code: 270,name: RepairedReplicaSetNode}
+ - {code: 271,name: JSInterpreterFailureWithStack,extra: JSExceptionInfo}
+ - {code: 272,name: MigrationConflict,categories: [SnapshotError]}
+ - {code: 273,name: ProducerConsumerQueueProducerQueueDepthExceeded}
+ - {code: 274,name: ProducerConsumerQueueConsumed}
+ - {code: 275,name: ExchangePassthrough} # For exchange execution in aggregation. Do not reuse.
+ - {code: 276,name: IndexBuildAborted}
+ - {code: 277,name: AlarmAlreadyFulfilled}
+ - {code: 278,name: UnsatisfiableCommitQuorum}
+ - {code: 279,name: ClientDisconnect,categories: [Interruption]}
+ - {code: 280,name: ChangeStreamFatalError,categories: [NonResumableChangeStreamError]}
# The two codes below are for internal use only and must never be returned in a network response
- - {code: 281, name: TransactionCoordinatorSteppingDown} # Gets converted to InterruptedDueToReplStateChange
- - {code: 282, name: TransactionCoordinatorReachedAbortDecision}
+ - {code: 281,name: TransactionCoordinatorSteppingDown} # Gets converted to InterruptedDueToReplStateChange
+ - {code: 282,name: TransactionCoordinatorReachedAbortDecision}
- - {code: 283, name: WouldChangeOwningShard, extra: WouldChangeOwningShardInfo}
- - {code: 284, name: ForTestingErrorExtraInfoWithExtraInfoInNamespace,
+ - {code: 283,name: WouldChangeOwningShard,extra: WouldChangeOwningShardInfo}
+ - {code: 284,name: ForTestingErrorExtraInfoWithExtraInfoInNamespace,
extra: 'nested::twice::NestedErrorExtraInfoExample'}
- - {code: 285, name: IndexBuildAlreadyInProgress}
- - {code: 286, name: ChangeStreamHistoryLost, categories: [NonResumableChangeStreamError]}
+ - {code: 285,name: IndexBuildAlreadyInProgress}
+ - {code: 286,name: ChangeStreamHistoryLost,categories: [NonResumableChangeStreamError]}
# The code below is for internal use only and must never be returned in a network response
- - {code: 287, name: TransactionCoordinatorDeadlineTaskCanceled}
+ - {code: 287,name: TransactionCoordinatorDeadlineTaskCanceled}
- - {code: 288, name: ChecksumMismatch, categories: [ConnectionFatalMessageParseError]}
+ - {code: 288,name: ChecksumMismatch,categories: [ConnectionFatalMessageParseError]}
# Internal only code used by WaitForMajorityService.
- - {code: 289, name: WaitForMajorityServiceEarlierOpTimeAvailable}
+ - {code: 289,name: WaitForMajorityServiceEarlierOpTimeAvailable}
- - {code: 290, name: TransactionExceededLifetimeLimitSeconds, categories: [ExceededTimeLimitError]}
+ - {code: 290,name: TransactionExceededLifetimeLimitSeconds,categories: [ExceededTimeLimitError]}
# Error codes 4000-8999 are reserved.
# Non-sequential error codes for compatibility only)
- - {code: 9001, name: SocketException, categories: [NetworkError]}
- - {code: 9996, name: OBSOLETE_RecvStaleConfig}
- - {code: 10003, name: CannotGrowDocumentInCappedNamespace}
- - {code: 10107, name: NotMaster, categories: [NotMasterError]}
- - {code: 10334, name: BSONObjectTooLarge}
- - {code: 11000, name: DuplicateKey, extra: DuplicateKeyErrorInfo}
- - {code: 11600, name: InterruptedAtShutdown, categories: [Interruption,ShutdownError,CancelationError]}
- - {code: 11601, name: Interrupted, categories: [Interruption]}
- - {code: 11602, name: InterruptedDueToReplStateChange, categories: [Interruption,NotMasterError]}
- - {code: 12586, name: BackgroundOperationInProgressForDatabase}
- - {code: 12587, name: BackgroundOperationInProgressForNamespace}
- - {code: 13104, name: OBSOLETE_PrepareConfigsFailed}
- - {code: 13113, name: MergeStageNoMatchingDocument}
- - {code: 13297, name: DatabaseDifferCase}
- - {code: 13388, name: StaleConfig,
+ - {code: 9001,name: SocketException,categories: [NetworkError,RetriableError]}
+ - {code: 9996,name: OBSOLETE_RecvStaleConfig}
+ - {code: 10003,name: CannotGrowDocumentInCappedNamespace}
+ - {code: 10107,name: NotMaster,categories: [NotMasterError,RetriableError]}
+ - {code: 10334,name: BSONObjectTooLarge}
+ - {code: 11000,name: DuplicateKey,extra: DuplicateKeyErrorInfo}
+ - {code: 11600,name: InterruptedAtShutdown,categories: [Interruption,ShutdownError,CancelationError,RetriableError]}
+ - {code: 11601,name: Interrupted,categories: [Interruption]}
+ - {code: 11602,name: InterruptedDueToReplStateChange,categories: [Interruption,NotMasterError,RetriableError]}
+ - {code: 12586,name: BackgroundOperationInProgressForDatabase}
+ - {code: 12587,name: BackgroundOperationInProgressForNamespace}
+ - {code: 13104,name: OBSOLETE_PrepareConfigsFailed}
+ - {code: 13113,name: MergeStageNoMatchingDocument}
+ - {code: 13297,name: DatabaseDifferCase}
+ - {code: 13388,name: StaleConfig,
extra: StaleConfigInfo,
- categories: [StaleShardVersionError, NeedRetargettingError]}
- - {code: 13435, name: NotMasterNoSlaveOk, categories: [NotMasterError]}
- - {code: 13436, name: NotMasterOrSecondary, categories: [NotMasterError]}
- - {code: 14031, name: OutOfDiskSpace}
- - {code: 17280, name: OSBELETE_KeyTooLong}
+ categories: [StaleShardVersionError,NeedRetargettingError]}
+ - {code: 13435,name: NotMasterNoSlaveOk,categories: [NotMasterError,RetriableError]}
+ - {code: 13436,name: NotMasterOrSecondary,categories: [NotMasterError,RetriableError]}
+ - {code: 14031,name: OutOfDiskSpace}
+ - {code: 17280,name: OSBELETE_KeyTooLong}
diff --git a/src/mongo/client/fetcher_test.cpp b/src/mongo/client/fetcher_test.cpp
index f0fa26cf7b3..d835e89b594 100644
--- a/src/mongo/client/fetcher_test.cpp
+++ b/src/mongo/client/fetcher_test.cpp
@@ -986,10 +986,8 @@ TEST_F(FetcherTest, ShutdownDuringSecondBatch) {
}
TEST_F(FetcherTest, FetcherAppliesRetryPolicyToFirstCommandButNotToGetMoreRequests) {
- auto policy = RemoteCommandRetryScheduler::makeRetryPolicy(
- 3U,
- executor::RemoteCommandRequest::kNoTimeout,
- {ErrorCodes::BadValue, ErrorCodes::InternalError});
+ auto policy = RemoteCommandRetryScheduler::makeRetryPolicy<ErrorCategory::RetriableError>(
+ 3U, executor::RemoteCommandRequest::kNoTimeout);
fetcher = std::make_unique<Fetcher>(&getExecutor(),
source,
@@ -1007,9 +1005,9 @@ TEST_F(FetcherTest, FetcherAppliesRetryPolicyToFirstCommandButNotToGetMoreReques
// Retry policy is applied to find command.
const BSONObj doc = BSON("_id" << 1);
- auto rs = ResponseStatus(ErrorCodes::BadValue, "first", Milliseconds(0));
+ auto rs = ResponseStatus(ErrorCodes::HostUnreachable, "first", Milliseconds(0));
processNetworkResponse(rs, ReadyQueueState::kHasReadyRequests, FetcherState::kActive);
- rs = ResponseStatus(ErrorCodes::InternalError, "second", Milliseconds(0));
+ rs = ResponseStatus(ErrorCodes::SocketException, "second", Milliseconds(0));
processNetworkResponse(rs, ReadyQueueState::kHasReadyRequests, FetcherState::kActive);
processNetworkResponse(BSON("cursor" << BSON("id" << 1LL << "ns"
<< "db.coll"
diff --git a/src/mongo/client/remote_command_retry_scheduler.cpp b/src/mongo/client/remote_command_retry_scheduler.cpp
index 347c6043a6a..b8eaf0d951f 100644
--- a/src/mongo/client/remote_command_retry_scheduler.cpp
+++ b/src/mongo/client/remote_command_retry_scheduler.cpp
@@ -42,95 +42,6 @@
namespace mongo {
-namespace {
-
-class RetryPolicyImpl : public RemoteCommandRetryScheduler::RetryPolicy {
-public:
- RetryPolicyImpl(std::size_t maximumAttempts,
- Milliseconds maximumResponseElapsedTotal,
- const std::initializer_list<ErrorCodes::Error>& retryableErrors);
- std::size_t getMaximumAttempts() const override;
- Milliseconds getMaximumResponseElapsedTotal() const override;
- bool shouldRetryOnError(ErrorCodes::Error error) const override;
- std::string toString() const override;
-
-private:
- std::size_t _maximumAttempts;
- Milliseconds _maximumResponseElapsedTotal;
- std::vector<ErrorCodes::Error> _retryableErrors;
-};
-
-RetryPolicyImpl::RetryPolicyImpl(std::size_t maximumAttempts,
- Milliseconds maximumResponseElapsedTotal,
- const std::initializer_list<ErrorCodes::Error>& retryableErrors)
- : _maximumAttempts(maximumAttempts),
- _maximumResponseElapsedTotal(maximumResponseElapsedTotal),
- _retryableErrors(retryableErrors) {
- std::sort(_retryableErrors.begin(), _retryableErrors.end());
-}
-
-std::string RetryPolicyImpl::toString() const {
- str::stream output;
- output << "RetryPolicyImpl";
- output << " maxAttempts: " << _maximumAttempts;
- output << " maxTimeMillis: " << _maximumResponseElapsedTotal;
-
- if (_retryableErrors.size() > 0) {
- output << "Retryable Errors: ";
- for (auto error : _retryableErrors) {
- output << error;
- }
- }
- return output;
-}
-
-std::size_t RetryPolicyImpl::getMaximumAttempts() const {
- return _maximumAttempts;
-}
-
-Milliseconds RetryPolicyImpl::getMaximumResponseElapsedTotal() const {
- return _maximumResponseElapsedTotal;
-}
-
-bool RetryPolicyImpl::shouldRetryOnError(ErrorCodes::Error error) const {
- return std::binary_search(_retryableErrors.cbegin(), _retryableErrors.cend(), error);
-}
-
-} // namespace
-
-const std::initializer_list<ErrorCodes::Error> RemoteCommandRetryScheduler::kNotMasterErrors{
- ErrorCodes::NotMaster, ErrorCodes::NotMasterNoSlaveOk, ErrorCodes::NotMasterOrSecondary};
-
-const std::initializer_list<ErrorCodes::Error> RemoteCommandRetryScheduler::kAllRetriableErrors{
- ErrorCodes::NotMaster,
- ErrorCodes::NotMasterNoSlaveOk,
- ErrorCodes::NotMasterOrSecondary,
- // If write concern failed to be satisfied on the remote server, this most probably means that
- // some of the secondary nodes were unreachable or otherwise unresponsive, so the call is safe
- // to be retried if idempotency can be guaranteed.
- ErrorCodes::WriteConcernFailed,
- ErrorCodes::HostUnreachable,
- ErrorCodes::HostNotFound,
- ErrorCodes::NetworkTimeout,
- ErrorCodes::PrimarySteppedDown,
- ErrorCodes::InterruptedDueToReplStateChange,
- ErrorCodes::BalancerInterrupted};
-
-std::unique_ptr<RemoteCommandRetryScheduler::RetryPolicy>
-RemoteCommandRetryScheduler::makeNoRetryPolicy() {
- return makeRetryPolicy(1U, executor::RemoteCommandRequest::kNoTimeout, {});
-}
-
-std::unique_ptr<RemoteCommandRetryScheduler::RetryPolicy>
-RemoteCommandRetryScheduler::makeRetryPolicy(
- std::size_t maxAttempts,
- Milliseconds maxResponseElapsedTotal,
- const std::initializer_list<ErrorCodes::Error>& retryableErrors) {
- std::unique_ptr<RetryPolicy> policy =
- std::make_unique<RetryPolicyImpl>(maxAttempts, maxResponseElapsedTotal, retryableErrors);
- return policy;
-}
-
RemoteCommandRetryScheduler::RemoteCommandRetryScheduler(
executor::TaskExecutor* executor,
const executor::RemoteCommandRequest& request,
diff --git a/src/mongo/client/remote_command_retry_scheduler.h b/src/mongo/client/remote_command_retry_scheduler.h
index 82766f7ca18..b4cfe52ef88 100644
--- a/src/mongo/client/remote_command_retry_scheduler.h
+++ b/src/mongo/client/remote_command_retry_scheduler.h
@@ -33,6 +33,8 @@
#include <initializer_list>
#include <memory>
+#include <fmt/format.h>
+
#include "mongo/base/error_codes.h"
#include "mongo/executor/task_executor.h"
#include "mongo/stdx/condition_variable.h"
@@ -64,16 +66,6 @@ public:
class RetryPolicy;
/**
- * List of not master error codes.
- */
- static const std::initializer_list<ErrorCodes::Error> kNotMasterErrors;
-
- /**
- * List of retriable error codes.
- */
- static const std::initializer_list<ErrorCodes::Error> kAllRetriableErrors;
-
- /**
* Generates a retry policy that will send the remote command request to the source at most
* once.
*/
@@ -81,15 +73,12 @@ public:
/**
* Creates a retry policy that will send the remote command request at most "maxAttempts".
- * This policy will also direct the scheduler to stop retrying if it encounters any of the
- * errors in "nonRetryableErrors".
* (Requires SERVER-24067) The scheduler will also stop retrying if the total elapsed time
* of all failed requests exceeds "maxResponseElapsedTotal".
*/
- static std::unique_ptr<RetryPolicy> makeRetryPolicy(
- std::size_t maxAttempts,
- Milliseconds maxResponseElapsedTotal,
- const std::initializer_list<ErrorCodes::Error>& retryableErrors);
+ template <ErrorCategory kCategory>
+ static std::unique_ptr<RetryPolicy> makeRetryPolicy(std::size_t maxAttempts,
+ Milliseconds maxResponseElapsedTotal);
/**
* Creates scheduler but does not schedule any remote command request.
@@ -128,6 +117,10 @@ public:
std::string toString() const;
private:
+ class NoRetryPolicy;
+ template <ErrorCategory kCategory>
+ class RetryPolicyForCategory;
+
/**
* Schedules remote command to be run by the executor.
* "requestCount" is number of requests scheduled before calling this function.
@@ -207,4 +200,69 @@ public:
virtual std::string toString() const = 0;
};
+class RemoteCommandRetryScheduler::NoRetryPolicy final
+ : public RemoteCommandRetryScheduler::RetryPolicy {
+public:
+ std::size_t getMaximumAttempts() const override {
+ return 1U;
+ }
+
+ Milliseconds getMaximumResponseElapsedTotal() const override {
+ return executor::RemoteCommandRequest::kNoTimeout;
+ }
+
+ bool shouldRetryOnError(ErrorCodes::Error error) const override {
+ return false;
+ }
+
+ std::string toString() const override {
+ return R"!({type: "NoRetryPolicy"})!";
+ }
+};
+
+inline auto RemoteCommandRetryScheduler::makeNoRetryPolicy() -> std::unique_ptr<RetryPolicy> {
+ return std::make_unique<NoRetryPolicy>();
+}
+
+template <ErrorCategory kCategory>
+class RemoteCommandRetryScheduler::RetryPolicyForCategory final
+ : public RemoteCommandRetryScheduler::RetryPolicy {
+public:
+ RetryPolicyForCategory(std::size_t maximumAttempts, Milliseconds maximumResponseElapsedTotal)
+ : _maximumAttempts(maximumAttempts),
+ _maximumResponseElapsedTotal(maximumResponseElapsedTotal){};
+
+ std::size_t getMaximumAttempts() const override {
+ return _maximumAttempts;
+ }
+
+ Milliseconds getMaximumResponseElapsedTotal() const override {
+ return _maximumResponseElapsedTotal;
+ }
+
+ bool shouldRetryOnError(ErrorCodes::Error error) const override {
+ return ErrorCodes::isA<kCategory>(error);
+ }
+
+ std::string toString() const override {
+ using namespace fmt::literals;
+ return R"!({{type: "RetryPolicyForCategory",categoryIndex: {}, maxAttempts: {}, maxTimeMS: {}}})!"_format(
+ static_cast<std::underlying_type_t<ErrorCategory>>(kCategory),
+ _maximumAttempts,
+ _maximumResponseElapsedTotal.count());
+ }
+
+private:
+ std::size_t _maximumAttempts;
+ Milliseconds _maximumResponseElapsedTotal;
+};
+
+template <ErrorCategory kCategory>
+auto RemoteCommandRetryScheduler::makeRetryPolicy(std::size_t maxAttempts,
+ Milliseconds maxResponseElapsedTotal)
+ -> std::unique_ptr<RetryPolicy> {
+ return std::make_unique<RetryPolicyForCategory<kCategory>>(maxAttempts,
+ maxResponseElapsedTotal);
+}
+
} // namespace mongo
diff --git a/src/mongo/client/remote_command_retry_scheduler_test.cpp b/src/mongo/client/remote_command_retry_scheduler_test.cpp
index 7940be98674..63932072063 100644
--- a/src/mongo/client/remote_command_retry_scheduler_test.cpp
+++ b/src/mongo/client/remote_command_retry_scheduler_test.cpp
@@ -184,16 +184,13 @@ TEST_F(RemoteCommandRetrySchedulerTest, MakeSingleShotRetryPolicy) {
}
TEST_F(RemoteCommandRetrySchedulerTest, MakeRetryPolicy) {
- auto policy = RemoteCommandRetryScheduler::makeRetryPolicy(
- 5U,
- Milliseconds(100),
- {ErrorCodes::FailedToParse, ErrorCodes::InvalidNamespace, ErrorCodes::InternalError});
+ auto policy = RemoteCommandRetryScheduler::makeRetryPolicy<ErrorCategory::Interruption>(
+ 5U, Milliseconds(100));
ASSERT_EQUALS(5U, policy->getMaximumAttempts());
ASSERT_EQUALS(Milliseconds(100), policy->getMaximumResponseElapsedTotal());
for (int i = 0; i < int(ErrorCodes::MaxError); ++i) {
auto error = ErrorCodes::Error(i);
- if (error == ErrorCodes::InternalError || error == ErrorCodes::FailedToParse ||
- error == ErrorCodes::InvalidNamespace) {
+ if (ErrorCodes::isA<ErrorCategory::Interruption>(error)) {
ASSERT_TRUE(policy->shouldRetryOnError(error));
continue;
}
@@ -271,7 +268,8 @@ TEST_F(RemoteCommandRetrySchedulerTest, InvalidConstruction) {
&getExecutor(),
request,
callback,
- RemoteCommandRetryScheduler::makeRetryPolicy(0, Milliseconds(100), {})),
+ RemoteCommandRetryScheduler::makeRetryPolicy<ErrorCategory::RetriableError>(
+ 0, Milliseconds(100))),
AssertionException,
ErrorCodes::BadValue,
"policy max attempts cannot be zero");
@@ -282,7 +280,8 @@ TEST_F(RemoteCommandRetrySchedulerTest, InvalidConstruction) {
&getExecutor(),
request,
callback,
- RemoteCommandRetryScheduler::makeRetryPolicy(1U, Milliseconds(-100), {})),
+ RemoteCommandRetryScheduler::makeRetryPolicy<ErrorCategory::RetriableError>(
+ 1U, Milliseconds(-100))),
AssertionException,
ErrorCodes::BadValue,
"policy max response elapsed total cannot be negative");
@@ -317,8 +316,8 @@ TEST_F(RemoteCommandRetrySchedulerTest, StartupFailsWhenSchedulerIsShutDown) {
TEST_F(RemoteCommandRetrySchedulerTest,
ShuttingDownExecutorAfterSchedulerStartupInvokesCallbackWithCallbackCanceledError) {
CallbackResponseSaver callback;
- auto policy = RemoteCommandRetryScheduler::makeRetryPolicy(
- 10U, Milliseconds(1), {ErrorCodes::HostUnreachable});
+ auto policy = RemoteCommandRetryScheduler::makeRetryPolicy<ErrorCategory::RetriableError>(
+ 10U, Milliseconds(1));
RemoteCommandRetryScheduler scheduler(
&getExecutor(), request, std::ref(callback), std::move(policy));
start(&scheduler);
@@ -339,8 +338,8 @@ TEST_F(RemoteCommandRetrySchedulerTest,
TEST_F(RemoteCommandRetrySchedulerTest,
ShuttingDownSchedulerAfterSchedulerStartupInvokesCallbackWithCallbackCanceledError) {
CallbackResponseSaver callback;
- auto policy = RemoteCommandRetryScheduler::makeRetryPolicy(
- 10U, Milliseconds(1), {ErrorCodes::HostUnreachable});
+ auto policy = RemoteCommandRetryScheduler::makeRetryPolicy<ErrorCategory::RetriableError>(
+ 10U, Milliseconds(1));
RemoteCommandRetryScheduler scheduler(
&getExecutor(), request, std::ref(callback), std::move(policy));
start(&scheduler);
@@ -354,8 +353,8 @@ TEST_F(RemoteCommandRetrySchedulerTest,
TEST_F(RemoteCommandRetrySchedulerTest, SchedulerInvokesCallbackOnNonRetryableErrorInResponse) {
CallbackResponseSaver callback;
- auto policy = RemoteCommandRetryScheduler::makeRetryPolicy(
- 10U, Milliseconds(1), RemoteCommandRetryScheduler::kNotMasterErrors);
+ auto policy = RemoteCommandRetryScheduler::makeRetryPolicy<ErrorCategory::NotMasterError>(
+ 10U, Milliseconds(1));
RemoteCommandRetryScheduler scheduler(
&getExecutor(), request, std::ref(callback), std::move(policy));
start(&scheduler);
@@ -371,8 +370,8 @@ TEST_F(RemoteCommandRetrySchedulerTest, SchedulerInvokesCallbackOnNonRetryableEr
TEST_F(RemoteCommandRetrySchedulerTest, SchedulerInvokesCallbackOnFirstSuccessfulResponse) {
CallbackResponseSaver callback;
- auto policy = RemoteCommandRetryScheduler::makeRetryPolicy(
- 10U, Milliseconds(1), {ErrorCodes::HostUnreachable});
+ auto policy = RemoteCommandRetryScheduler::makeRetryPolicy<ErrorCategory::RetriableError>(
+ 10U, Milliseconds(1));
RemoteCommandRetryScheduler scheduler(
&getExecutor(), request, std::ref(callback), std::move(policy));
start(&scheduler);
@@ -390,8 +389,8 @@ TEST_F(RemoteCommandRetrySchedulerTest, SchedulerInvokesCallbackOnFirstSuccessfu
TEST_F(RemoteCommandRetrySchedulerTest, SchedulerIgnoresEmbeddedErrorInSuccessfulResponse) {
CallbackResponseSaver callback;
- auto policy = RemoteCommandRetryScheduler::makeRetryPolicy(
- 10U, Milliseconds(1), {ErrorCodes::HostUnreachable});
+ auto policy = RemoteCommandRetryScheduler::makeRetryPolicy<ErrorCategory::RetriableError>(
+ 10U, Milliseconds(1));
RemoteCommandRetryScheduler scheduler(
&getExecutor(), request, std::ref(callback), std::move(policy));
start(&scheduler);
@@ -411,8 +410,8 @@ TEST_F(RemoteCommandRetrySchedulerTest, SchedulerIgnoresEmbeddedErrorInSuccessfu
TEST_F(RemoteCommandRetrySchedulerTest,
SchedulerInvokesCallbackWithErrorFromExecutorIfScheduleRemoteCommandFailsOnRetry) {
CallbackResponseSaver callback;
- auto policy = RemoteCommandRetryScheduler::makeRetryPolicy(
- 3U, executor::RemoteCommandRequest::kNoTimeout, {ErrorCodes::HostNotFound});
+ auto policy = RemoteCommandRetryScheduler::makeRetryPolicy<ErrorCategory::RetriableError>(
+ 3U, executor::RemoteCommandRequest::kNoTimeout);
TaskExecutorWithFailureInScheduleRemoteCommand badExecutor(&getExecutor());
RemoteCommandRetryScheduler scheduler(
&badExecutor, request, std::ref(callback), std::move(policy));
@@ -432,10 +431,8 @@ TEST_F(RemoteCommandRetrySchedulerTest,
TEST_F(RemoteCommandRetrySchedulerTest,
SchedulerEnforcesPolicyMaximumAttemptsAndReturnsErrorOfLastFailedRequest) {
CallbackResponseSaver callback;
- auto policy = RemoteCommandRetryScheduler::makeRetryPolicy(
- 3U,
- executor::RemoteCommandRequest::kNoTimeout,
- RemoteCommandRetryScheduler::kAllRetriableErrors);
+ auto policy = RemoteCommandRetryScheduler::makeRetryPolicy<ErrorCategory::RetriableError>(
+ 3U, executor::RemoteCommandRequest::kNoTimeout);
RemoteCommandRetryScheduler scheduler(
&getExecutor(), request, std::ref(callback), std::move(policy));
start(&scheduler);
@@ -450,8 +447,8 @@ TEST_F(RemoteCommandRetrySchedulerTest,
TEST_F(RemoteCommandRetrySchedulerTest, SchedulerShouldRetryUntilSuccessfulResponseIsReceived) {
CallbackResponseSaver callback;
- auto policy = RemoteCommandRetryScheduler::makeRetryPolicy(
- 3U, executor::RemoteCommandRequest::kNoTimeout, {ErrorCodes::HostNotFound});
+ auto policy = RemoteCommandRetryScheduler::makeRetryPolicy<ErrorCategory::RetriableError>(
+ 3U, executor::RemoteCommandRequest::kNoTimeout);
RemoteCommandRetryScheduler scheduler(
&getExecutor(), request, std::ref(callback), std::move(policy));
start(&scheduler);
diff --git a/src/mongo/db/repl/collection_cloner.cpp b/src/mongo/db/repl/collection_cloner.cpp
index d6c17b38cfd..b081be1fce0 100644
--- a/src/mongo/db/repl/collection_cloner.cpp
+++ b/src/mongo/db/repl/collection_cloner.cpp
@@ -122,10 +122,9 @@ CollectionCloner::CollectionCloner(executor::TaskExecutor* executor,
[this](const executor::TaskExecutor::RemoteCommandCallbackArgs& args) {
return _countCallback(args);
},
- RemoteCommandRetryScheduler::makeRetryPolicy(
+ RemoteCommandRetryScheduler::makeRetryPolicy<ErrorCategory::RetriableError>(
numInitialSyncCollectionCountAttempts.load(),
- executor::RemoteCommandRequest::kNoTimeout,
- RemoteCommandRetryScheduler::kAllRetriableErrors)),
+ executor::RemoteCommandRequest::kNoTimeout)),
_listIndexesFetcher(
_executor,
_source,
@@ -139,10 +138,9 @@ CollectionCloner::CollectionCloner(executor::TaskExecutor* executor,
ReadPreferenceSetting::secondaryPreferredMetadata(),
RemoteCommandRequest::kNoTimeout /* find network timeout */,
RemoteCommandRequest::kNoTimeout /* getMore network timeout */,
- RemoteCommandRetryScheduler::makeRetryPolicy(
+ RemoteCommandRetryScheduler::makeRetryPolicy<ErrorCategory::RetriableError>(
numInitialSyncListIndexesAttempts.load(),
- executor::RemoteCommandRequest::kNoTimeout,
- RemoteCommandRetryScheduler::kAllRetriableErrors)),
+ executor::RemoteCommandRequest::kNoTimeout)),
_indexSpecs(),
_documentsToInsert(),
_dbWorkTaskRunner(_dbWorkThreadPool),
diff --git a/src/mongo/db/repl/database_cloner.cpp b/src/mongo/db/repl/database_cloner.cpp
index a0415918a54..5a26e80195d 100644
--- a/src/mongo/db/repl/database_cloner.cpp
+++ b/src/mongo/db/repl/database_cloner.cpp
@@ -112,22 +112,22 @@ DatabaseCloner::DatabaseCloner(executor::TaskExecutor* executor,
_storageInterface(si),
_collectionWork(collWork),
_onCompletion(std::move(onCompletion)),
- _listCollectionsFetcher(_executor,
- _source,
- _dbname,
- createListCollectionsCommandObject(_listCollectionsFilter),
- [=](const StatusWith<Fetcher::QueryResponse>& result,
- Fetcher::NextAction* nextAction,
- BSONObjBuilder* getMoreBob) {
- _listCollectionsCallback(result, nextAction, getMoreBob);
- },
- ReadPreferenceSetting::secondaryPreferredMetadata(),
- RemoteCommandRequest::kNoTimeout /* find network timeout */,
- RemoteCommandRequest::kNoTimeout /* getMore network timeout */,
- RemoteCommandRetryScheduler::makeRetryPolicy(
- numInitialSyncListCollectionsAttempts.load(),
- executor::RemoteCommandRequest::kNoTimeout,
- RemoteCommandRetryScheduler::kAllRetriableErrors)),
+ _listCollectionsFetcher(
+ _executor,
+ _source,
+ _dbname,
+ createListCollectionsCommandObject(_listCollectionsFilter),
+ [=](const StatusWith<Fetcher::QueryResponse>& result,
+ Fetcher::NextAction* nextAction,
+ BSONObjBuilder* getMoreBob) {
+ _listCollectionsCallback(result, nextAction, getMoreBob);
+ },
+ ReadPreferenceSetting::secondaryPreferredMetadata(),
+ RemoteCommandRequest::kNoTimeout /* find network timeout */,
+ RemoteCommandRequest::kNoTimeout /* getMore network timeout */,
+ RemoteCommandRetryScheduler::makeRetryPolicy<ErrorCategory::RetriableError>(
+ numInitialSyncListCollectionsAttempts.load(),
+ executor::RemoteCommandRequest::kNoTimeout)),
_startCollectionCloner([](CollectionCloner& cloner) { return cloner.startup(); }) {
// Fetcher throws an exception on null executor.
invariant(executor);
diff --git a/src/mongo/db/repl/databases_cloner.cpp b/src/mongo/db/repl/databases_cloner.cpp
index e2414897339..554acab9651 100644
--- a/src/mongo/db/repl/databases_cloner.cpp
+++ b/src/mongo/db/repl/databases_cloner.cpp
@@ -209,10 +209,9 @@ Status DatabasesCloner::startup() noexcept {
_exec,
listDBsReq,
[this](const auto& x) { this->_onListDatabaseFinish(x); },
- RemoteCommandRetryScheduler::makeRetryPolicy(
+ RemoteCommandRetryScheduler::makeRetryPolicy<ErrorCategory::RetriableError>(
numInitialSyncListDatabasesAttempts.load(),
- executor::RemoteCommandRequest::kNoTimeout,
- RemoteCommandRetryScheduler::kAllRetriableErrors));
+ executor::RemoteCommandRequest::kNoTimeout));
_status = _listDBsScheduler->startup();
if (!_status.isOK()) {
diff --git a/src/mongo/db/repl/initial_syncer.cpp b/src/mongo/db/repl/initial_syncer.cpp
index dc121c9072c..418899be19c 100644
--- a/src/mongo/db/repl/initial_syncer.cpp
+++ b/src/mongo/db/repl/initial_syncer.cpp
@@ -675,10 +675,8 @@ Status InitialSyncer::_scheduleGetBeginFetchingOpTime_inlock(
ReadPreferenceSetting::secondaryPreferredMetadata(),
RemoteCommandRequest::kNoTimeout /* find network timeout */,
RemoteCommandRequest::kNoTimeout /* getMore network timeout */,
- RemoteCommandRetryScheduler::makeRetryPolicy(
- numInitialSyncOplogFindAttempts.load(),
- executor::RemoteCommandRequest::kNoTimeout,
- RemoteCommandRetryScheduler::kAllRetriableErrors));
+ RemoteCommandRetryScheduler::makeRetryPolicy<ErrorCategory::RetriableError>(
+ numInitialSyncOplogFindAttempts.load(), executor::RemoteCommandRequest::kNoTimeout));
Status scheduleStatus = _beginFetchingOpTimeFetcher->schedule();
if (!scheduleStatus.isOK()) {
_beginFetchingOpTimeFetcher.reset();
@@ -799,10 +797,8 @@ void InitialSyncer::_lastOplogEntryFetcherCallbackForBeginApplyingTimestamp(
ReadPreferenceSetting::secondaryPreferredMetadata(),
RemoteCommandRequest::kNoTimeout /* find network timeout */,
RemoteCommandRequest::kNoTimeout /* getMore network timeout */,
- RemoteCommandRetryScheduler::makeRetryPolicy(
- numInitialSyncOplogFindAttempts.load(),
- executor::RemoteCommandRequest::kNoTimeout,
- RemoteCommandRetryScheduler::kAllRetriableErrors));
+ RemoteCommandRetryScheduler::makeRetryPolicy<ErrorCategory::RetriableError>(
+ numInitialSyncOplogFindAttempts.load(), executor::RemoteCommandRequest::kNoTimeout));
Status scheduleStatus = _fCVFetcher->schedule();
if (!scheduleStatus.isOK()) {
_fCVFetcher.reset();
@@ -1441,19 +1437,17 @@ Status InitialSyncer::_scheduleLastOplogEntryFetcher_inlock(Fetcher::CallbackFn
BSONObj query = BSON("find" << _opts.remoteOplogNS.coll() << "sort" << BSON("$natural" << -1)
<< "limit" << 1);
- _lastOplogEntryFetcher =
- std::make_unique<Fetcher>(_exec,
- _syncSource,
- _opts.remoteOplogNS.db().toString(),
- query,
- callback,
- ReadPreferenceSetting::secondaryPreferredMetadata(),
- RemoteCommandRequest::kNoTimeout /* find network timeout */,
- RemoteCommandRequest::kNoTimeout /* getMore network timeout */,
- RemoteCommandRetryScheduler::makeRetryPolicy(
- numInitialSyncOplogFindAttempts.load(),
- executor::RemoteCommandRequest::kNoTimeout,
- RemoteCommandRetryScheduler::kAllRetriableErrors));
+ _lastOplogEntryFetcher = std::make_unique<Fetcher>(
+ _exec,
+ _syncSource,
+ _opts.remoteOplogNS.db().toString(),
+ query,
+ callback,
+ ReadPreferenceSetting::secondaryPreferredMetadata(),
+ RemoteCommandRequest::kNoTimeout /* find network timeout */,
+ RemoteCommandRequest::kNoTimeout /* getMore network timeout */,
+ RemoteCommandRetryScheduler::makeRetryPolicy<ErrorCategory::RetriableError>(
+ numInitialSyncOplogFindAttempts.load(), executor::RemoteCommandRequest::kNoTimeout));
Status scheduleStatus = _lastOplogEntryFetcher->schedule();
if (!scheduleStatus.isOK()) {
_lastOplogEntryFetcher.reset();
diff --git a/src/mongo/s/client/shard.cpp b/src/mongo/s/client/shard.cpp
index e2c751529e2..d2b007a501a 100644
--- a/src/mongo/s/client/shard.cpp
+++ b/src/mongo/s/client/shard.cpp
@@ -93,10 +93,8 @@ Status Shard::CommandResponse::processBatchWriteResponse(
const Milliseconds Shard::kDefaultConfigCommandTimeout = Seconds{30};
bool Shard::shouldErrorBePropagated(ErrorCodes::Error code) {
- return std::find(RemoteCommandRetryScheduler::kAllRetriableErrors.begin(),
- RemoteCommandRetryScheduler::kAllRetriableErrors.end(),
- code) == RemoteCommandRetryScheduler::kAllRetriableErrors.end() &&
- code != ErrorCodes::NetworkInterfaceExceededTimeLimit;
+ return !ErrorCodes::isRetriableError(code) &&
+ (code != ErrorCodes::NetworkInterfaceExceededTimeLimit);
}
Shard::Shard(const ShardId& id) : _id(id) {}
diff --git a/src/mongo/s/client/shard_remote.cpp b/src/mongo/s/client/shard_remote.cpp
index 7d306e998f9..25f2e1959c0 100644
--- a/src/mongo/s/client/shard_remote.cpp
+++ b/src/mongo/s/client/shard_remote.cpp
@@ -106,14 +106,21 @@ bool ShardRemote::isRetriableError(ErrorCodes::Error code, RetryPolicy options)
return false;
}
- if (options == RetryPolicy::kNoRetry) {
- return false;
+ switch (options) {
+ case RetryPolicy::kNoRetry: {
+ return false;
+ } break;
+
+ case RetryPolicy::kIdempotent: {
+ return ErrorCodes::isRetriableError(code);
+ } break;
+
+ case RetryPolicy::kNotIdempotent: {
+ return ErrorCodes::isNotMasterError(code);
+ } break;
}
- const auto& retriableErrors = options == RetryPolicy::kIdempotent
- ? RemoteCommandRetryScheduler::kAllRetriableErrors
- : RemoteCommandRetryScheduler::kNotMasterErrors;
- return std::find(retriableErrors.begin(), retriableErrors.end(), code) != retriableErrors.end();
+ MONGO_UNREACHABLE;
}
const ConnectionString ShardRemote::getConnString() const {
diff --git a/src/mongo/s/query/establish_cursors.cpp b/src/mongo/s/query/establish_cursors.cpp
index b97f9026d03..a0ff0f6cb07 100644
--- a/src/mongo/s/query/establish_cursors.cpp
+++ b/src/mongo/s/query/establish_cursors.cpp
@@ -95,13 +95,9 @@ std::vector<RemoteCursor> establishCursors(OperationContext* opCtx,
uassertStatusOK(cursor.getStatus());
}
- } catch (const DBException& ex) {
+ } catch (const ExceptionForCat<ErrorCategory::RetriableError>&) {
// Retriable errors are swallowed if 'allowPartialResults' is true.
- if (allowPartialResults &&
- std::find(RemoteCommandRetryScheduler::kAllRetriableErrors.begin(),
- RemoteCommandRetryScheduler::kAllRetriableErrors.end(),
- ex.code()) !=
- RemoteCommandRetryScheduler::kAllRetriableErrors.end()) {
+ if (allowPartialResults) {
continue;
}
throw; // Fail this loop.
diff --git a/src/mongo/s/transaction_router.cpp b/src/mongo/s/transaction_router.cpp
index 5b791ab0270..81cd77fcab0 100644
--- a/src/mongo/s/transaction_router.cpp
+++ b/src/mongo/s/transaction_router.cpp
@@ -158,13 +158,6 @@ bool isReadConcernLevelAllowedInTransaction(repl::ReadConcernLevel readConcernLe
readConcernLevel == repl::ReadConcernLevel::kLocalReadConcern;
}
-// Returns if the error code would be considered a retryable error for a retryable write.
-bool isRetryableWritesError(ErrorCodes::Error code) {
- return std::find(RemoteCommandRetryScheduler::kAllRetriableErrors.begin(),
- RemoteCommandRetryScheduler::kAllRetriableErrors.end(),
- code) != RemoteCommandRetryScheduler::kAllRetriableErrors.end();
-}
-
// Returns if a transaction's commit result is unknown based on the given statuses. A result is
// considered unknown if it would be given the "UnknownTransactionCommitResult" as defined by the
// driver transactions specification or fails with one of the errors for invalid write concern that
@@ -176,8 +169,8 @@ bool isRetryableWritesError(ErrorCodes::Error code) {
// https://github.com/mongodb/specifications/blob/master/source/transactions/transactions.rst#unknowntransactioncommitresult.
bool isCommitResultUnknown(const Status& commitStatus, const Status& commitWCStatus) {
if (!commitStatus.isOK()) {
- return isRetryableWritesError(commitStatus.code()) ||
- ErrorCodes::isExceededTimeLimitError(commitStatus.code()) ||
+ return ErrorCodes::isRetriableError(commitStatus) ||
+ ErrorCodes::isExceededTimeLimitError(commitStatus) ||
commitStatus.code() == ErrorCodes::TransactionTooOld;
}
diff --git a/src/mongo/util/assert_util_test.cpp b/src/mongo/util/assert_util_test.cpp
index 05b33ea3e4b..754d747b5da 100644
--- a/src/mongo/util/assert_util_test.cpp
+++ b/src/mongo/util/assert_util_test.cpp
@@ -87,9 +87,10 @@ TEST(AssertUtils, UassertNamedCodeWithoutCategories) {
ASSERT_NOT_CATCHES(ErrorCodes::BadValue, ExceptionForCat<ErrorCategory::Interruption>);
}
-// NotMaster - just NotMasterError
+// NotMaster - NotMasterError, RetriableError
MONGO_STATIC_ASSERT(std::is_same<error_details::ErrorCategoriesFor<ErrorCodes::NotMaster>,
- error_details::CategoryList<ErrorCategory::NotMasterError>>());
+ error_details::CategoryList<ErrorCategory::NotMasterError,
+ ErrorCategory::RetriableError>>());
MONGO_STATIC_ASSERT(std::is_base_of<AssertionException, ExceptionFor<ErrorCodes::NotMaster>>());
MONGO_STATIC_ASSERT(!std::is_base_of<ExceptionForCat<ErrorCategory::NetworkError>,
ExceptionFor<ErrorCodes::NotMaster>>());
@@ -108,11 +109,12 @@ TEST(AssertUtils, UassertNamedCodeWithOneCategory) {
ASSERT_NOT_CATCHES(ErrorCodes::NotMaster, ExceptionForCat<ErrorCategory::Interruption>);
}
-// InterruptedDueToReplStateChange - NotMasterError and Interruption
+// InterruptedDueToReplStateChange - NotMasterError, Interruption, RetriableError
MONGO_STATIC_ASSERT(
- std::is_same<
- error_details::ErrorCategoriesFor<ErrorCodes::InterruptedDueToReplStateChange>,
- error_details::CategoryList<ErrorCategory::Interruption, ErrorCategory::NotMasterError>>());
+ std::is_same<error_details::ErrorCategoriesFor<ErrorCodes::InterruptedDueToReplStateChange>,
+ error_details::CategoryList<ErrorCategory::Interruption,
+ ErrorCategory::NotMasterError,
+ ErrorCategory::RetriableError>>());
MONGO_STATIC_ASSERT(std::is_base_of<AssertionException,
ExceptionFor<ErrorCodes::InterruptedDueToReplStateChange>>());
MONGO_STATIC_ASSERT(!std::is_base_of<ExceptionForCat<ErrorCategory::NetworkError>,