32
32
/* the caller knows either a client or server error has occurred.
33
33
* `reply` contains the server reply or an empty document. */
34
34
static bool
35
- _is_resumable_error (const bson_t * reply )
35
+ _is_resumable_error (mongoc_change_stream_t * stream , const bson_t * reply )
36
36
{
37
37
bson_error_t error = {0 };
38
38
@@ -46,28 +46,32 @@ _is_resumable_error (const bson_t *reply)
46
46
return true;
47
47
}
48
48
49
- if (mongoc_error_has_label (reply , "NonResumableChangeStreamError" )) {
50
- return false;
51
- }
52
-
53
- /* Change Streams Spec resumable criteria: "a server error response with an
54
- * error message containing the substring 'not master' or 'node is
55
- * recovering' */
56
- if (strstr (error .message , "not master" ) ||
57
- strstr (error .message , "node is recovering" )) {
58
- return true;
49
+ if (stream -> max_wire_version >= WIRE_VERSION_4_4 ) {
50
+ return mongoc_error_has_label (reply , "ResumableChangeStreamError" );
59
51
}
60
52
61
- /* Change Streams Spec resumable criteria: "any server error response from a
62
- * getMore command excluding those containing the following error codes" */
63
53
switch (error .code ) {
64
- case 11601 : /* Interrupted */
65
- case 136 : /* CappedPositionLost */
66
- case 237 : /* CursorKilled */
67
- case MONGOC_ERROR_QUERY_FAILURE : /* error code omitted */
68
- return false;
69
- default :
54
+ case 6 : /* HostUnreachable */
55
+ case 7 : /* HostNotFound */
56
+ case 89 : /* NetworkTimeout */
57
+ case 91 : /* ShutdownInProgress */
58
+ case 189 : /* PrimarySteppedDown */
59
+ case 262 : /* ExceededTimeLimit */
60
+ case 9001 : /* SocketException */
61
+ case 10107 : /* NotMaster */
62
+ case 11600 : /* InterruptedAtShutdown */
63
+ case 11602 : /* InterruptedDueToReplStateChange */
64
+ case 13435 : /* NotMasterNoSlaveOk */
65
+ case 13436 : /* NotMasterOrSecondary */
66
+ case 63 : /* StaleShardVersion */
67
+ case 150 : /* StaleEpoch */
68
+ case 13388 : /* StaleConfig */
69
+ case 234 : /* RetryChangeStream */
70
+ case 133 : /* FailedToSatisfyReadPreference */
71
+ case 216 : /* ElectionInProgress */
70
72
return true;
73
+ default :
74
+ return false;
71
75
}
72
76
}
73
77
@@ -93,9 +97,7 @@ _set_resume_token (mongoc_change_stream_t *stream, const bson_t *resume_token)
93
97
* cursor: { batchSize: x } }
94
98
*/
95
99
static void
96
- _make_command (mongoc_change_stream_t * stream ,
97
- bson_t * command ,
98
- int32_t max_wire_version )
100
+ _make_command (mongoc_change_stream_t * stream , bson_t * command )
99
101
{
100
102
bson_iter_t iter ;
101
103
bson_t change_stream_stage ; /* { $changeStream: <change_stream_doc> } */
@@ -135,7 +137,7 @@ _make_command (mongoc_change_stream_t *stream,
135
137
& change_stream_doc , "resumeAfter" , & stream -> resume_token );
136
138
}
137
139
} else if (!_mongoc_timestamp_empty (& stream -> operation_time ) &&
138
- max_wire_version >= 7 ) {
140
+ stream -> max_wire_version >= WIRE_VERSION_4_0 ) {
139
141
/* Else if there is no cached resumeToken and the ChangeStream
140
142
has a saved operation time and the max wire version is >= 7,
141
143
the driver MUST set startAtOperationTime */
@@ -231,7 +233,6 @@ _make_cursor (mongoc_change_stream_t *stream)
231
233
bson_iter_t iter ;
232
234
mongoc_server_description_t * sd ;
233
235
uint32_t server_id ;
234
- int32_t max_wire_version = -1 ;
235
236
236
237
BSON_ASSERT (stream );
237
238
BSON_ASSERT (!stream -> cursor );
@@ -245,7 +246,7 @@ _make_cursor (mongoc_change_stream_t *stream)
245
246
server_id = mongoc_server_description_id (sd );
246
247
bson_append_int32 (& command_opts , "serverId" , 8 , server_id );
247
248
bson_append_int32 (& getmore_opts , "serverId" , 8 , server_id );
248
- max_wire_version = sd -> max_wire_version ;
249
+ stream -> max_wire_version = sd -> max_wire_version ;
249
250
mongoc_server_description_destroy (sd );
250
251
251
252
if (bson_iter_init_find (& iter , & command_opts , "sessionId" )) {
@@ -288,7 +289,7 @@ _make_cursor (mongoc_change_stream_t *stream)
288
289
mongoc_read_concern_append (stream -> read_concern , & command_opts );
289
290
}
290
291
291
- _make_command (stream , & command , max_wire_version );
292
+ _make_command (stream , & command );
292
293
293
294
/* even though serverId has already been set, still pass the read prefs.
294
295
* they are necessary for OP_MSG if sending to a secondary. */
@@ -350,7 +351,8 @@ _make_cursor (mongoc_change_stream_t *stream)
350
351
if (bson_empty (& stream -> opts .resumeAfter ) &&
351
352
bson_empty (& stream -> opts .startAfter ) &&
352
353
_mongoc_timestamp_empty (& stream -> operation_time ) &&
353
- max_wire_version >= 7 && bson_empty (& stream -> resume_token ) &&
354
+ stream -> max_wire_version >= WIRE_VERSION_4_0 &&
355
+ bson_empty (& stream -> resume_token ) &&
354
356
bson_iter_init_find (
355
357
& iter ,
356
358
_mongoc_cursor_change_stream_get_reply (stream -> cursor ),
@@ -529,7 +531,7 @@ mongoc_change_stream_next (mongoc_change_stream_t *stream, const bson_t **bson)
529
531
goto end ;
530
532
}
531
533
532
- resumable = _is_resumable_error (err_doc );
534
+ resumable = _is_resumable_error (stream , err_doc );
533
535
while (resumable ) {
534
536
/* recreate the cursor. */
535
537
mongoc_cursor_destroy (stream -> cursor );
@@ -545,7 +547,7 @@ mongoc_change_stream_next (mongoc_change_stream_t *stream, const bson_t **bson)
545
547
goto end ;
546
548
}
547
549
if (err_doc ) {
548
- resumable = _is_resumable_error (err_doc );
550
+ resumable = _is_resumable_error (stream , err_doc );
549
551
} else {
550
552
resumable = false;
551
553
}
0 commit comments