Skip to content

Commit 1a0f9a9

Browse files
committed
CDRIVER-1933 smallest maxStalenessSeconds is 90
Revert code to parse "idleWritePeriodMillis" from ismaster, and revert changes that allowed maxStalenessSeconds to be a float. Sync JSON tests from specs repo.
1 parent 248193e commit 1a0f9a9

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+239
-426
lines changed

doc/mongoc_read_prefs_get_max_staleness_seconds.page

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
<section id="synopsis">
1414
<title>Synopsis</title>
15-
<synopsis><code mime="text/x-csrc"><![CDATA[double
15+
<synopsis><code mime="text/x-csrc"><![CDATA[int64_t
1616
mongoc_read_prefs_get_max_staleness_seconds (const mongoc_read_prefs_t *read_prefs);
1717
]]></code></synopsis>
1818
</section>
@@ -26,7 +26,7 @@ mongoc_read_prefs_get_max_staleness_seconds (const mongoc_read_prefs_t *read_pre
2626

2727
<section id="description">
2828
<title>Description</title>
29-
<p>Clients estimate the staleness of each secondary, and select for reads only those secondaries whose estimated staleness is less than or equal to maxStalenessSeconds. The default is -1, meaning no maximum staleness.</p>
29+
<p>Clients estimate the staleness of each secondary, and select for reads only those secondaries whose estimated staleness is less than or equal to maxStalenessSeconds. The default is <code>MONGOC_NO_MAX_STALENESS</code>.</p>
3030
</section>
3131

3232
</page>

doc/mongoc_read_prefs_set_max_staleness_seconds.page

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,14 @@
1414
<title>Synopsis</title>
1515
<synopsis><code mime="text/x-csrc"><![CDATA[void
1616
mongoc_read_prefs_set_max_staleness_seconds (mongoc_read_prefs_t *read_prefs,
17-
double max_staleness_seconds);]]></code></synopsis>
17+
int64_t max_staleness_seconds);]]></code></synopsis>
1818
</section>
1919

2020
<section id="parameters">
2121
<title>Parameters</title>
2222
<table>
2323
<tr><td><p>read_prefs</p></td><td><p>A <code xref="mongoc_read_prefs_t">mongoc_read_prefs_t</code>.</p></td></tr>
24-
<tr><td><p>max_staleness_seconds</p></td><td><p>A positive number or -1 (meaning no maximum).</p></td></tr>
24+
<tr><td><p>max_staleness_seconds</p></td><td><p>A positive integer or <code>MONGOC_NO_MAX_STALENESS</code>.</p></td></tr>
2525
</table>
2626
</section>
2727

doc/mongoc_read_prefs_t.page

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,13 @@
6161
<p>All interfaces use the same member selection logic to choose the member to which to direct read operations, basing the choice on read preference mode and tag sets.</p>
6262
</section>
6363

64+
<section id="max-staleness-seconds">
65+
<title>Max Staleness</title>
66+
<p>When connected to replica set running MongoDB 3.4 or later, the driver estimates the staleness of each secondary based on lastWriteDate values provided in server isMaster responses.</p>
67+
<p>Max Staleness is the maximum replication lag in seconds (wall clock time) that a secondary can suffer and still be eligible for reads. The default is <code>MONGOC_NO_MAX_STALENESS</code>, which disables staleness checks. Otherwise, it must be a positive integer at least <code>MONGOC_SMALLEST_MAX_STALENESS_SECONDS</code> (90 seconds).</p>
68+
<p>Max Staleness is also supported by sharded clusters of replica sets if all servers run MongoDB 3.4 or later.</p>
69+
</section>
70+
6471
<links type="topic" groups="function" style="2column">
6572
<title>Functions</title>
6673
</links>

src/mongoc/mongoc-read-prefs-private.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,11 @@
2929

3030
BSON_BEGIN_DECLS
3131

32-
#define NO_MAX_STALENESS (-1.0)
33-
3432
struct _mongoc_read_prefs_t
3533
{
3634
mongoc_read_mode_t mode;
3735
bson_t tags;
38-
double max_staleness_seconds;
36+
int64_t max_staleness_seconds;
3937
};
4038

4139

src/mongoc/mongoc-read-prefs.c

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ mongoc_read_prefs_new (mongoc_read_mode_t mode)
2929
read_prefs = (mongoc_read_prefs_t *)bson_malloc0(sizeof *read_prefs);
3030
read_prefs->mode = mode;
3131
bson_init(&read_prefs->tags);
32-
read_prefs->max_staleness_seconds = NO_MAX_STALENESS;
32+
read_prefs->max_staleness_seconds = MONGOC_NO_MAX_STALENESS;
3333

3434
return read_prefs;
3535
}
@@ -98,7 +98,7 @@ mongoc_read_prefs_add_tag (mongoc_read_prefs_t *read_prefs,
9898
}
9999

100100

101-
double
101+
int64_t
102102
mongoc_read_prefs_get_max_staleness_seconds (const mongoc_read_prefs_t *read_prefs)
103103
{
104104
BSON_ASSERT (read_prefs);
@@ -109,7 +109,7 @@ mongoc_read_prefs_get_max_staleness_seconds (const mongoc_read_prefs_t *read_pre
109109

110110
void
111111
mongoc_read_prefs_set_max_staleness_seconds (mongoc_read_prefs_t *read_prefs,
112-
double max_staleness_seconds)
112+
int64_t max_staleness_seconds)
113113
{
114114
BSON_ASSERT (read_prefs);
115115

@@ -127,13 +127,13 @@ mongoc_read_prefs_is_valid (const mongoc_read_prefs_t *read_prefs)
127127
*/
128128
if (read_prefs->mode == MONGOC_READ_PRIMARY) {
129129
if (!bson_empty(&read_prefs->tags) ||
130-
read_prefs->max_staleness_seconds != NO_MAX_STALENESS) {
130+
read_prefs->max_staleness_seconds != MONGOC_NO_MAX_STALENESS) {
131131
return false;
132132
}
133133
}
134134

135-
if (read_prefs->max_staleness_seconds != NO_MAX_STALENESS &&
136-
read_prefs->max_staleness_seconds <= 0.0) {
135+
if (read_prefs->max_staleness_seconds != MONGOC_NO_MAX_STALENESS &&
136+
read_prefs->max_staleness_seconds <= 0) {
137137
return false;
138138
}
139139

@@ -198,7 +198,7 @@ _apply_read_preferences_mongos (const mongoc_read_prefs_t *read_prefs,
198198
const bson_t *tags = NULL;
199199
bson_t child;
200200
const char *mode_str;
201-
double max_staleness_seconds;
201+
int64_t max_staleness_seconds;
202202

203203
mode = mongoc_read_prefs_get_mode (read_prefs);
204204
if (read_prefs) {
@@ -257,9 +257,9 @@ _apply_read_preferences_mongos (const mongoc_read_prefs_t *read_prefs,
257257
max_staleness_seconds = mongoc_read_prefs_get_max_staleness_seconds (
258258
read_prefs);
259259

260-
if (max_staleness_seconds != NO_MAX_STALENESS) {
261-
bson_append_double (&child, "maxStalenessSeconds", 19,
262-
max_staleness_seconds);
260+
if (max_staleness_seconds != MONGOC_NO_MAX_STALENESS) {
261+
bson_append_int64 (&child, "maxStalenessSeconds", 19,
262+
max_staleness_seconds);
263263
}
264264

265265
bson_append_document_end (result->query_with_read_prefs, &child);

src/mongoc/mongoc-read-prefs.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@
2828
BSON_BEGIN_DECLS
2929

3030

31+
#define MONGOC_NO_MAX_STALENESS -1
32+
#define MONGOC_SMALLEST_MAX_STALENESS_SECONDS 90
33+
3134
typedef struct _mongoc_read_prefs_t mongoc_read_prefs_t;
3235

3336

@@ -61,10 +64,10 @@ BSON_API
6164
void mongoc_read_prefs_add_tag (mongoc_read_prefs_t *read_prefs,
6265
const bson_t *tag);
6366
BSON_API
64-
double mongoc_read_prefs_get_max_staleness_seconds (const mongoc_read_prefs_t *read_prefs);
67+
int64_t mongoc_read_prefs_get_max_staleness_seconds (const mongoc_read_prefs_t *read_prefs);
6568
BSON_API
6669
void mongoc_read_prefs_set_max_staleness_seconds (mongoc_read_prefs_t *read_prefs,
67-
double max_staleness_seconds);
70+
int64_t max_staleness_seconds);
6871
BSON_API
6972
bool mongoc_read_prefs_is_valid (const mongoc_read_prefs_t *read_prefs);
7073

src/mongoc/mongoc-server-description-private.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
#define MONGOC_DEFAULT_WRITE_BATCH_SIZE 1000
2525
#define MONGOC_DEFAULT_BSON_OBJ_SIZE 16 * 1024 * 1024
2626
#define MONGOC_DEFAULT_MAX_MSG_SIZE 48000000
27-
#define MONGOC_DEFAULT_IDLE_WRITE_PERIOD_MS 10 * 1000
27+
#define MONGOC_IDLE_WRITE_PERIOD_MS 10 * 1000
2828

2929
/* represent a server or topology with no replica set config version */
3030
#define MONGOC_NO_SET_VERSION -1
@@ -75,7 +75,6 @@ struct _mongoc_server_description_t
7575
int64_t set_version;
7676
bson_oid_t election_id;
7777
int64_t last_write_date_ms;
78-
int64_t idle_write_period_ms;
7978
};
8079

8180
void

src/mongoc/mongoc-server-description.c

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,6 @@ mongoc_server_description_reset (mongoc_server_description_t *sd)
6363
sd->max_bson_obj_size = MONGOC_DEFAULT_BSON_OBJ_SIZE;
6464
sd->max_write_batch_size = MONGOC_DEFAULT_WRITE_BATCH_SIZE;
6565
sd->last_write_date_ms = -1;
66-
sd->idle_write_period_ms = -1;
6766

6867
/* always leave last ismaster in an init-ed state until we destroy sd */
6968
bson_destroy (&sd->last_is_master);
@@ -121,7 +120,6 @@ mongoc_server_description_init (mongoc_server_description_t *sd,
121120
sd->max_bson_obj_size = MONGOC_DEFAULT_BSON_OBJ_SIZE;
122121
sd->max_write_batch_size = MONGOC_DEFAULT_WRITE_BATCH_SIZE;
123122
sd->last_write_date_ms = -1;
124-
sd->idle_write_period_ms = -1;
125123

126124
bson_init_static (&sd->hosts, kMongocEmptyBson, sizeof (kMongocEmptyBson));
127125
bson_init_static (&sd->passives, kMongocEmptyBson, sizeof (kMongocEmptyBson));
@@ -699,13 +697,13 @@ mongoc_server_description_filter_stale (mongoc_server_description_t **sds,
699697
int64_t heartbeat_frequency_ms,
700698
const mongoc_read_prefs_t *read_prefs)
701699
{
702-
double max_staleness_seconds;
700+
int64_t max_staleness_seconds;
703701
size_t i;
704702

705703
int64_t heartbeat_frequency_usec;
706704
int64_t max_last_write_date_usec;
707705
int64_t staleness_usec;
708-
double max_staleness_usec;
706+
int64_t max_staleness_usec;
709707

710708
if (!read_prefs) {
711709
/* NULL read_prefs is PRIMARY, no maxStalenessSeconds to filter by */
@@ -715,11 +713,11 @@ mongoc_server_description_filter_stale (mongoc_server_description_t **sds,
715713
max_staleness_seconds = mongoc_read_prefs_get_max_staleness_seconds (
716714
read_prefs);
717715

718-
if (max_staleness_seconds == NO_MAX_STALENESS) {
716+
if (max_staleness_seconds == MONGOC_NO_MAX_STALENESS) {
719717
return;
720718
}
721719

722-
BSON_ASSERT (max_staleness_seconds >= 0);
720+
BSON_ASSERT (max_staleness_seconds > 0);
723721
max_staleness_usec = max_staleness_seconds * 1000 * 1000;
724722
heartbeat_frequency_usec = heartbeat_frequency_ms * 1000;
725723

src/mongoc/mongoc-topology-description-private.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ mongoc_topology_description_all_sds_have_write_date (
102102
bool
103103
_mongoc_topology_description_validate_max_staleness (
104104
const mongoc_topology_description_t *td,
105-
double max_staleness_seconds,
105+
int64_t max_staleness_seconds,
106106
bson_error_t *error);
107107

108108
void

src/mongoc/mongoc-topology-description.c

Lines changed: 26 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -505,78 +505,44 @@ mongoc_topology_description_all_sds_have_write_date (const mongoc_topology_descr
505505
bool
506506
_mongoc_topology_description_validate_max_staleness (
507507
const mongoc_topology_description_t *td,
508-
double max_staleness_seconds,
508+
int64_t max_staleness_seconds,
509509
bson_error_t *error)
510510
{
511-
int i;
512-
mongoc_server_description_t *sd;
513-
int64_t idle_write_period_ms = -1;
514-
515-
if (max_staleness_seconds == NO_MAX_STALENESS) {
516-
return true;
517-
}
518-
519-
/* The isMaster response of a replica set member running some future
520-
* MongoDB version may contain idleWritePeriodMillis. Choose the
521-
* primary's value or else the most recently updated secondary's value,
522-
* according to the Server Selection Spec.
511+
mongoc_topology_description_type_t td_type;
512+
513+
/* Server Selection Spec: A driver MUST raise an error if the TopologyType
514+
* is ReplicaSetWithPrimary or ReplicaSetNoPrimary and either of these
515+
* conditions is false:
516+
*
517+
* maxStalenessSeconds * 1000 >= heartbeatFrequencyMS + idleWritePeriodMS
518+
* maxStalenessSeconds >= smallestMaxStalenessSeconds
523519
*/
524-
if (td->type == MONGOC_TOPOLOGY_RS_WITH_PRIMARY) {
525-
mongoc_server_description_t *primary = NULL;
526-
527-
for (i = 0; i < td->servers->items_len; i++) {
528-
sd = (mongoc_server_description_t *) mongoc_set_get_item (
529-
td->servers, i);
530-
531-
if (sd->type == MONGOC_SERVER_RS_PRIMARY) {
532-
primary = sd;
533-
break;
534-
}
535-
}
536-
537-
BSON_ASSERT (primary);
538-
539-
idle_write_period_ms = primary->idle_write_period_ms;
540-
} else if (td->type == MONGOC_TOPOLOGY_RS_NO_PRIMARY) {
541-
mongoc_server_description_t *last_updated = NULL;
542-
543-
for (i = 0; i < td->servers->items_len; i++) {
544-
sd = (mongoc_server_description_t *) mongoc_set_get_item (
545-
td->servers, i);
546520

547-
if (sd->type != MONGOC_SERVER_RS_SECONDARY) {
548-
continue;
549-
}
550-
551-
if (!last_updated ||
552-
sd->last_update_time_usec > last_updated->last_update_time_usec) {
553-
last_updated = sd;
554-
}
555-
}
556-
557-
if (!last_updated) {
558-
/* no secondaries */
559-
return true;
560-
}
521+
td_type = td->type;
561522

562-
idle_write_period_ms = last_updated->idle_write_period_ms;
563-
} else {
564-
/* topology is not a replica set */
523+
if (td_type != MONGOC_TOPOLOGY_RS_WITH_PRIMARY &&
524+
td_type != MONGOC_TOPOLOGY_RS_NO_PRIMARY) {
565525
return true;
566526
}
567527

568-
if (idle_write_period_ms == -1) {
569-
idle_write_period_ms = MONGOC_DEFAULT_IDLE_WRITE_PERIOD_MS;
528+
if (max_staleness_seconds * 1000 <
529+
td->heartbeat_msec + MONGOC_IDLE_WRITE_PERIOD_MS) {
530+
bson_set_error (error, MONGOC_ERROR_COMMAND,
531+
MONGOC_ERROR_COMMAND_INVALID_ARG,
532+
"maxStalenessSeconds is set to %" PRId64
533+
", it must be at least heartbeatFrequencyMS (%" PRId64
534+
") + server's idle write period (%d seconds)",
535+
max_staleness_seconds, td->heartbeat_msec,
536+
MONGOC_IDLE_WRITE_PERIOD_MS / 1000);
537+
return false;
570538
}
571539

572-
if (max_staleness_seconds * 1000 <
573-
td->heartbeat_msec + idle_write_period_ms) {
540+
if (max_staleness_seconds < MONGOC_SMALLEST_MAX_STALENESS_SECONDS) {
574541
bson_set_error (error, MONGOC_ERROR_COMMAND,
575542
MONGOC_ERROR_COMMAND_INVALID_ARG,
576-
"maxStalenessSeconds must be at least"
577-
" heartbeatFrequencyMS (%" PRId64 ") +"
578-
" server's idleWritePeriodMillis (%" PRId64 ")",
579-
td->heartbeat_msec, idle_write_period_ms);
543+
"maxStalenessSeconds is set to %" PRId64
544+
", it must be at least %d seconds", max_staleness_seconds,
545+
MONGOC_SMALLEST_MAX_STALENESS_SECONDS);
580546
return false;
581547
}
582548

0 commit comments

Comments
 (0)