diff --git a/src/operations/execute_operation.ts b/src/operations/execute_operation.ts index 6b74920aa69..0715a5f0704 100644 --- a/src/operations/execute_operation.ts +++ b/src/operations/execute_operation.ts @@ -324,6 +324,26 @@ async function executeOperationWithRetries< throw error; } + if ( + operationError instanceof MongoNetworkError && + operation.hasAspect(Aspect.CURSOR_CREATING) && + session != null && + session.isPinned && + !session.inTransaction() + ) { + session.unpin({ force: true, forceClear: true }); + } + + if ( + operationError.hasErrorLabel(MongoErrorLabel.SystemOverloadedError) && + operation.hasAspect(Aspect.CURSOR_CREATING) && + session != null && + session.isPinned && + !session.inTransaction() + ) { + session.unpin({ force: true }); + } + if (operationError.hasErrorLabel(MongoErrorLabel.SystemOverloadedError)) { const backoffMS = Math.random() * Math.min(MAX_BACKOFF_MS, BASE_BACKOFF_MS * 2 ** attempt); @@ -339,16 +359,6 @@ async function executeOperationWithRetries< await setTimeout(backoffMS); } - if ( - operationError instanceof MongoNetworkError && - operation.hasAspect(Aspect.CURSOR_CREATING) && - session != null && - session.isPinned && - !session.inTransaction() - ) { - session.unpin({ force: true, forceClear: true }); - } - if ( topology.description.type === TopologyType.Sharded || operationError.hasErrorLabel(MongoErrorLabel.SystemOverloadedError) diff --git a/test/spec/client-backpressure/backpressure-connection-checkin.json b/test/spec/client-backpressure/backpressure-connection-checkin.json new file mode 100644 index 00000000000..340c87c0142 --- /dev/null +++ b/test/spec/client-backpressure/backpressure-connection-checkin.json @@ -0,0 +1,129 @@ +{ + "description": "tests that connections are returned to the pool on retry attempts for overload errors", + "schemaVersion": "1.3", + "runOnRequirements": [ + { + "minServerVersion": "4.4", + "topologies": [ + "replicaset", + "sharded", + "load-balanced" + ] + } + ], + "createEntities": [ + { + "client": { + "id": "client", + "useMultipleMongoses": false, + "observeEvents": [ + "connectionCheckedOutEvent", + "connectionCheckedInEvent" + ] + } + }, + { + "client": { + "id": "fail_point_client", + "useMultipleMongoses": false + } + }, + { + "database": { + "id": "database", + "client": "client", + "databaseName": "backpressure-connection-checkin" + } + }, + { + "collection": { + "id": "collection", + "database": "database", + "collectionName": "coll" + } + } + ], + "tests": [ + { + "description": "overload error retry attempts return connections to the pool", + "operations": [ + { + "name": "failPoint", + "object": "testRunner", + "arguments": { + "client": "fail_point_client", + "failPoint": { + "configureFailPoint": "failCommand", + "mode": "alwaysOn", + "data": { + "failCommands": [ + "find" + ], + "errorLabels": [ + "RetryableError", + "SystemOverloadedError" + ], + "errorCode": 2 + } + } + } + }, + { + "name": "find", + "object": "collection", + "arguments": { + "filter": {} + }, + "expectError": { + "isError": true, + "isClientError": false + } + } + ], + "expectEvents": [ + { + "client": "client", + "eventType": "cmap", + "events": [ + { + "connectionCheckedOutEvent": {} + }, + { + "connectionCheckedInEvent": {} + }, + { + "connectionCheckedOutEvent": {} + }, + { + "connectionCheckedInEvent": {} + }, + { + "connectionCheckedOutEvent": {} + }, + { + "connectionCheckedInEvent": {} + }, + { + "connectionCheckedOutEvent": {} + }, + { + "connectionCheckedInEvent": {} + }, + { + "connectionCheckedOutEvent": {} + }, + { + "connectionCheckedInEvent": {} + }, + { + "connectionCheckedOutEvent": {} + }, + { + "connectionCheckedInEvent": {} + } + ] + } + ] + } + ] +} diff --git a/test/spec/client-backpressure/backpressure-connection-checkin.yml b/test/spec/client-backpressure/backpressure-connection-checkin.yml new file mode 100644 index 00000000000..7c4359335c3 --- /dev/null +++ b/test/spec/client-backpressure/backpressure-connection-checkin.yml @@ -0,0 +1,67 @@ +description: tests that connections are returned to the pool on retry attempts for overload errors +schemaVersion: "1.3" +runOnRequirements: + - minServerVersion: "4.4" + topologies: + - replicaset + - sharded + - load-balanced +createEntities: + - client: + id: client + useMultipleMongoses: false + observeEvents: + - connectionCheckedOutEvent + - connectionCheckedInEvent + - client: + id: fail_point_client + useMultipleMongoses: false + - database: + id: database + client: client + databaseName: backpressure-connection-checkin + - collection: + id: collection + database: database + collectionName: coll +tests: + - description: overload error retry attempts return connections to the pool + operations: + - name: failPoint + object: testRunner + arguments: + client: fail_point_client + failPoint: + configureFailPoint: failCommand + mode: alwaysOn + data: + failCommands: + - find + errorLabels: + - RetryableError + - SystemOverloadedError + errorCode: 2 + - name: find + object: collection + arguments: + filter: {} + expectError: + isError: true + isClientError: false + expectEvents: + - client: client + eventType: cmap + events: + - connectionCheckedOutEvent: {} + - connectionCheckedInEvent: {} + - connectionCheckedOutEvent: {} + - connectionCheckedInEvent: {} + - connectionCheckedOutEvent: {} + - connectionCheckedInEvent: {} + - connectionCheckedOutEvent: {} + - connectionCheckedInEvent: {} + - connectionCheckedOutEvent: {} + - connectionCheckedInEvent: {} + - connectionCheckedOutEvent: {} + - connectionCheckedInEvent: {} +