-
Notifications
You must be signed in to change notification settings - Fork 153
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
RUST-885 Support snapshot sessions #390
Conversation
@@ -120,11 +131,21 @@ impl CommandResponse { | |||
let cluster_time = raw_response | |||
.get("$clusterTime") | |||
.and_then(|subdoc| bson::from_bson(subdoc.clone()).ok()); | |||
let snapshot_time = raw_response |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My initial approach was to add atClusterTime
as an explicit field in the output of the relevant commands (find, aggregate, distinct), but that required:
- introducing a trait for the output type of an operation, which added a lot of churn, and
- additional special handling in operations implemented on top of one of those three (e.g. countDocuments).
The approach here avoids both of those issues at the cost of digging a bit into the raw document.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As part of #389, I actually did have to introduce a trait for the output type of an operation (there was definitely a lot of churn, but for that work it was required I think), so we could still go with your original plan once that PR is merged. For the purposes of avoiding merge conflicts, I think it'll probably be easier to merge this PR first though and then rebase #389 off of that and adjust for atClusterTime
accordingly there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, with that trait existing it definitely makes sense to go back to extracting the snapshot time that way. Your plan for merging SGTM.
src/concern/mod.rs
Outdated
#[non_exhaustive] | ||
pub struct ReadConcern { | ||
/// The level of the read concern. | ||
pub level: ReadConcernLevel, | ||
|
||
/// The snapshot read timestamp. | ||
#[serde(skip_serializing_if = "Option::is_none")] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The server rejects commands with atClusterTime: null
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Out of curiosity, would adding #[serde(skip_serializing_none)]
to the ReadConcern
struct do the trick here as well? We use that for a lot of our options structs but I'm wondering if that would break other behavior here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, I'd missed that, thank you! It looks like that works as well, updated to be consistent with the rest of the codebase.
@@ -152,22 +153,20 @@ pub(crate) struct CursorSpecification { | |||
|
|||
impl CursorSpecification { | |||
pub(crate) fn new( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This refactor was in service of being able to pass an at_cluster_time
field through easily, but even without that it seemed worthwhile to leave in.
src/error.rs
Outdated
/// The server version does not support the operation. | ||
#[error("The server version does not support a database operation: {message}")] | ||
#[non_exhaustive] | ||
ServerVersion { message: String }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you think about naming this IncompatibleServerVersion
instead for some added clarity? Or even IncompatibleServer
in case there are more criteria in the future unrelated to server version that may cause an operation to fail?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good call, done.
@@ -120,11 +131,21 @@ impl CommandResponse { | |||
let cluster_time = raw_response | |||
.get("$clusterTime") | |||
.and_then(|subdoc| bson::from_bson(subdoc.clone()).ok()); | |||
let snapshot_time = raw_response |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As part of #389, I actually did have to introduce a trait for the output type of an operation (there was definitely a lot of churn, but for that work it was required I think), so we could still go with your original plan once that PR is merged. For the purposes of avoiding merge conflicts, I think it'll probably be easier to merge this PR first though and then rebase #389 off of that and adjust for atClusterTime
accordingly there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
src/client/mod.rs
Outdated
self.list_databases_common(filter, options, None).await | ||
} | ||
|
||
/// Gets information about each database present in the cluster the Client is connected to. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we add "using the provided ClientSession
" to this doc (in the same vein as e.g. this)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good call, done.
src/concern/mod.rs
Outdated
#[non_exhaustive] | ||
pub struct ReadConcern { | ||
/// The level of the read concern. | ||
pub level: ReadConcernLevel, | ||
|
||
/// The snapshot read timestamp. | ||
#[serde(skip_serializing_if = "Option::is_none")] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Out of curiosity, would adding #[serde(skip_serializing_none)]
to the ReadConcern
struct do the trick here as well? We use that for a lot of our options structs but I'm wondering if that would break other behavior here.
a37d41a
to
02df866
Compare
RUST-885
This adds support for the
snapshot
session option, and the associated client-side machinery to track read operation session timestamps. This also fixes RUST-878 and RUST-879.