Skip to content

Commit d65b4d8

Browse files
committed
CDRIVER-1079 network err from command resets server
1 parent 42f2674 commit d65b4d8

9 files changed

+395
-14
lines changed

src/mongoc/mongoc-client.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1244,6 +1244,7 @@ mongoc_client_command_simple (mongoc_client_t *client,
12441244
MONGOC_QUERY_NONE, &result);
12451245

12461246
ret = mongoc_cluster_run_command (cluster, server_stream->stream,
1247+
server_stream->sd->id,
12471248
result.flags, db_name,
12481249
result.query_with_read_prefs,
12491250
reply, error);
@@ -1333,6 +1334,7 @@ _mongoc_client_killcursors_command (mongoc_cluster_t *cluster,
13331334
* killCursors command MAY be safely ignored."
13341335
*/
13351336
mongoc_cluster_run_command (cluster, server_stream->stream,
1337+
server_stream->sd->id,
13361338
MONGOC_QUERY_SLAVE_OK, db, &command,
13371339
NULL, NULL);
13381340

src/mongoc/mongoc-cluster-private.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ mongoc_cluster_stream_for_server (mongoc_cluster_t *cluster,
128128
bool
129129
mongoc_cluster_run_command_rpc (mongoc_cluster_t *cluster,
130130
mongoc_stream_t *stream,
131+
uint32_t server_id,
131132
const char *command_name,
132133
mongoc_rpc_t *rpc,
133134
mongoc_rpc_t *reply_rpc,
@@ -137,6 +138,7 @@ mongoc_cluster_run_command_rpc (mongoc_cluster_t *cluster,
137138
bool
138139
mongoc_cluster_run_command (mongoc_cluster_t *cluster,
139140
mongoc_stream_t *stream,
141+
uint32_t server_id,
140142
mongoc_query_flags_t flags,
141143
const char *db_name,
142144
const bson_t *command,

src/mongoc/mongoc-cluster.c

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -115,13 +115,16 @@ _bson_error_message_printf (bson_error_t *error,
115115
*
116116
* Side effects:
117117
* On success, @buffer and @reply_rpc are filled out with the reply.
118+
* On failure, @error is filled out. If this was a network error
119+
* and server_id is nonzero, the cluster disconnects from the server.
118120
*
119121
*--------------------------------------------------------------------------
120122
*/
121123

122124
bool
123125
mongoc_cluster_run_command_rpc (mongoc_cluster_t *cluster,
124126
mongoc_stream_t *stream,
127+
uint32_t server_id,
125128
const char *command_name,
126129
mongoc_rpc_t *rpc,
127130
mongoc_rpc_t *reply_rpc,
@@ -158,6 +161,9 @@ mongoc_cluster_run_command_rpc (mongoc_cluster_t *cluster,
158161
cluster->sockettimeoutms, error) ||
159162
!_mongoc_buffer_append_from_stream (buffer, stream, 4,
160163
cluster->sockettimeoutms, error)) {
164+
165+
mongoc_cluster_disconnect_node (cluster, server_id);
166+
161167
/* add info about the command to writev_full's error message */
162168
_mongoc_get_db_name (rpc->query.collection, db);
163169
_bson_error_message_printf (
@@ -222,13 +228,16 @@ mongoc_cluster_run_command_rpc (mongoc_cluster_t *cluster,
222228
*
223229
* Side effects:
224230
* @reply is set and should ALWAYS be released with bson_destroy().
231+
* On failure, @error is filled out. If this was a network error
232+
* and server_id is nonzero, the cluster disconnects from the server.
225233
*
226234
*--------------------------------------------------------------------------
227235
*/
228236

229237
bool
230238
mongoc_cluster_run_command (mongoc_cluster_t *cluster,
231239
mongoc_stream_t *stream,
240+
uint32_t server_id,
232241
mongoc_query_flags_t flags,
233242
const char *db_name,
234243
const bson_t *command,
@@ -249,7 +258,7 @@ mongoc_cluster_run_command (mongoc_cluster_t *cluster,
249258
_mongoc_rpc_prep_command (&rpc, ns, command, flags);
250259

251260
/* we can reuse the query rpc for the reply */
252-
if (!mongoc_cluster_run_command_rpc (cluster, stream,
261+
if (!mongoc_cluster_run_command_rpc (cluster, stream, server_id,
253262
_mongoc_get_command_name (command),
254263
&rpc, &rpc, &buffer, error)) {
255264
GOTO (done);
@@ -320,7 +329,7 @@ _mongoc_stream_run_ismaster (mongoc_cluster_t *cluster,
320329
bson_init (&command);
321330
bson_append_int32 (&command, "ismaster", 8, 1);
322331

323-
ret = mongoc_cluster_run_command (cluster, stream, MONGOC_QUERY_SLAVE_OK,
332+
ret = mongoc_cluster_run_command (cluster, stream, 0, MONGOC_QUERY_SLAVE_OK,
324333
"admin", &command, reply, error);
325334

326335
bson_destroy (&command);
@@ -514,7 +523,7 @@ _mongoc_cluster_auth_node_cr (mongoc_cluster_t *cluster,
514523
*/
515524
bson_init (&command);
516525
bson_append_int32 (&command, "getnonce", 8, 1);
517-
if (!mongoc_cluster_run_command (cluster, stream, MONGOC_QUERY_SLAVE_OK,
526+
if (!mongoc_cluster_run_command (cluster, stream, 0, MONGOC_QUERY_SLAVE_OK,
518527
auth_source, &command, &reply, error)) {
519528
bson_destroy (&command);
520529
bson_destroy (&reply);
@@ -549,7 +558,7 @@ _mongoc_cluster_auth_node_cr (mongoc_cluster_t *cluster,
549558
* Execute the authenticate command. mongoc_cluster_run_command
550559
* checks for {ok: 1} in the response.
551560
*/
552-
ret = mongoc_cluster_run_command (cluster, stream, MONGOC_QUERY_SLAVE_OK,
561+
ret = mongoc_cluster_run_command (cluster, stream, 0, MONGOC_QUERY_SLAVE_OK,
553562
auth_source, &command, &reply, error);
554563
if (!ret) {
555564
/* error->message is already set */
@@ -739,7 +748,7 @@ _mongoc_cluster_auth_node_sasl (mongoc_cluster_t *cluster,
739748
mongoc_uri_get_username (cluster->uri),
740749
sasl.step);
741750

742-
if (!mongoc_cluster_run_command (cluster, stream, MONGOC_QUERY_SLAVE_OK,
751+
if (!mongoc_cluster_run_command (cluster, stream, 0, MONGOC_QUERY_SLAVE_OK,
743752
"$external", &cmd, &reply, error)) {
744753
bson_destroy (&cmd);
745754
bson_destroy (&reply);
@@ -862,7 +871,7 @@ _mongoc_cluster_auth_node_plain (mongoc_cluster_t *cluster,
862871
bson_append_utf8 (&b, "payload", 7, (const char *)buf, buflen);
863872
BSON_APPEND_INT32 (&b, "autoAuthorize", 1);
864873

865-
ret = mongoc_cluster_run_command (cluster, stream, MONGOC_QUERY_SLAVE_OK,
874+
ret = mongoc_cluster_run_command (cluster, stream, 0, MONGOC_QUERY_SLAVE_OK,
866875
"$external", &b, &reply, error);
867876

868877
if (!ret) {
@@ -916,7 +925,7 @@ _mongoc_cluster_auth_node_x509 (mongoc_cluster_t *cluster,
916925
BSON_APPEND_UTF8 (&cmd, "mechanism", "MONGODB-X509");
917926
BSON_APPEND_UTF8 (&cmd, "user", username);
918927

919-
ret = mongoc_cluster_run_command (cluster, stream, MONGOC_QUERY_SLAVE_OK,
928+
ret = mongoc_cluster_run_command (cluster, stream, 0, MONGOC_QUERY_SLAVE_OK,
920929
"$external", &cmd, &reply, error);
921930

922931
if (!ret) {
@@ -986,7 +995,7 @@ _mongoc_cluster_auth_node_scram (mongoc_cluster_t *cluster,
986995
mongoc_uri_get_username (cluster->uri),
987996
scram.step);
988997

989-
if (!mongoc_cluster_run_command (cluster, stream, MONGOC_QUERY_SLAVE_OK,
998+
if (!mongoc_cluster_run_command (cluster, stream, 0, MONGOC_QUERY_SLAVE_OK,
990999
auth_source, &cmd, &reply, error)) {
9911000
bson_destroy (&cmd);
9921001
bson_destroy (&reply);
@@ -2035,6 +2044,8 @@ _mongoc_cluster_check_interval (mongoc_cluster_t *cluster,
20352044
if (scanner_node->last_used + (1000 * CHECK_CLOSED_DURATION_MSEC) < now) {
20362045
if (mongoc_stream_check_closed (stream)) {
20372046
mongoc_cluster_disconnect_node (cluster, server_id);
2047+
bson_set_error (error, MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_SOCKET,
2048+
"Stream is closed");
20382049
return false;
20392050
}
20402051
}
@@ -2045,9 +2056,9 @@ _mongoc_cluster_check_interval (mongoc_cluster_t *cluster,
20452056
BSON_APPEND_INT32 (&command, "ismaster", 1);
20462057

20472058
before_ismaster = now;
2048-
2049-
r = mongoc_cluster_run_command (cluster, stream, MONGOC_QUERY_SLAVE_OK,
2050-
"admin", &command, &reply, error);
2059+
r = mongoc_cluster_run_command (cluster, stream, server_id,
2060+
MONGOC_QUERY_SLAVE_OK, "admin", &command,
2061+
&reply, error);
20512062

20522063
now = bson_get_monotonic_time ();
20532064

src/mongoc/mongoc-collection.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -710,6 +710,7 @@ mongoc_collection_count_with_opts (mongoc_collection_t *collection, /* IN
710710
}
711711

712712
success = mongoc_cluster_run_command (cluster, server_stream->stream,
713+
server_stream->sd->id,
713714
MONGOC_QUERY_SLAVE_OK, collection->db,
714715
&cmd, &reply, error);
715716

@@ -2161,6 +2162,7 @@ mongoc_collection_find_and_modify_with_opts (mongoc_collection_t
21612162
}
21622163

21632164
ret = mongoc_cluster_run_command (cluster, server_stream->stream,
2165+
server_stream->sd->id,
21642166
MONGOC_QUERY_NONE, collection->db,
21652167
&command, &reply_local, error);
21662168

src/mongoc/mongoc-cursor.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -537,6 +537,7 @@ _mongoc_cursor_run_command (mongoc_cursor_t *cursor,
537537
read_prefs_result.flags);
538538

539539
if (!mongoc_cluster_run_command_rpc (cluster, server_stream->stream,
540+
server_stream->sd->id,
540541
_mongoc_get_command_name (&cursor->query),
541542
&rpc, &cursor->rpc, &cursor->buffer,
542543
&cursor->error)) {

src/mongoc/mongoc-write-command.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -906,8 +906,8 @@ _mongoc_write_command(mongoc_write_command_t *command,
906906
ret = false;
907907
} else {
908908
ret = mongoc_cluster_run_command (&client->cluster, server_stream->stream,
909-
MONGOC_QUERY_NONE, database, &cmd,
910-
&reply, error);
909+
server_stream->sd->id, MONGOC_QUERY_NONE,
910+
database, &cmd, &reply, error);
911911

912912
if (!ret) {
913913
result->failed = true;

tests/TestSuite.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ extern "C" {
7171
#define ASSERT_CMPULONG(a, eq, b) ASSERT_CMPINT_HELPER(a, eq, b, "lu")
7272
#define ASSERT_CMPINT32(a, eq, b) ASSERT_CMPINT_HELPER(a, eq, b, PRId32)
7373
#define ASSERT_CMPINT64(a, eq, b) ASSERT_CMPINT_HELPER(a, eq, b, PRId64)
74+
#define ASSERT_CMPUINT16(a, eq, b) ASSERT_CMPINT_HELPER(a, eq, b, "hu")
7475
#define ASSERT_CMPUINT64(a, eq, b) ASSERT_CMPINT_HELPER(a, eq, b, PRIu64)
7576
#define ASSERT_CMPSIZE_T(a, eq, b) ASSERT_CMPINT_HELPER(a, eq, b, "zd")
7677
#define ASSERT_CMPSSIZE_T(a, eq, b) ASSERT_CMPINT_HELPER(a, eq, b, "zx")
@@ -171,6 +172,16 @@ extern "C" {
171172
ASSERT_CONTAINS (error.message, _message); \
172173
} while (0);
173174

175+
#define ASSERT_HAS_FIELD(_bson, _field) \
176+
do { \
177+
if (!bson_has_field ((_bson), (_field))) { \
178+
fprintf(stderr, \
179+
"FAIL\n\nAssert Failure: No field \"%s\" in \"%s\"\n", \
180+
(_field), bson_as_json (_bson, NULL)); \
181+
abort(); \
182+
} \
183+
} while (0)
184+
174185
#define MAX_TEST_NAME_LENGTH 500
175186

176187

0 commit comments

Comments
 (0)