@@ -74,6 +74,8 @@ class Session
7474 # and *:nearest*.
7575 # @option options [ true | false ] :snapshot Set up the session for
7676 # snapshot reads.
77+ # @option options [ BSON::Timestamp ] :snapshot_time The desired snapshot
78+ # time for snapshot reads. Only valid when :snapshot is true.
7779 #
7880 # @since 2.5.0
7981 # @api private
@@ -82,6 +84,14 @@ def initialize(server_session, client, options = {})
8284 raise ArgumentError , ':causal_consistency and :snapshot options cannot be both set on a session'
8385 end
8486
87+ if options [ :snapshot_time ] && !options [ :snapshot ]
88+ raise ArgumentError , ':snapshot_time can only be set when :snapshot is true'
89+ end
90+
91+ if options [ :snapshot_time ] && !options [ :snapshot_time ] . is_a? ( BSON ::Timestamp )
92+ raise ArgumentError , ':snapshot_time must be a BSON::Timestamp'
93+ end
94+
8595 if options [ :implicit ]
8696 unless server_session . nil?
8797 raise ArgumentError , 'Implicit session cannot reference server session during construction'
@@ -104,6 +114,7 @@ def initialize(server_session, client, options = {})
104114 @with_transaction_deadline = nil
105115 @with_transaction_timeout_ms = nil
106116 @inside_with_transaction = false
117+ @snapshot_timestamp = options [ :snapshot_time ]
107118 end
108119
109120 # @return [ Hash ] The options for this session.
@@ -1273,8 +1284,23 @@ def txn_num
12731284 @server_session . txn_num
12741285 end
12751286
1287+ # @return [ BSON::Timestamp | nil ] The snapshot time for this session.
1288+ # nil if the session is not a snapshot session, or if it is a snapshot
1289+ # session for which no :snapshot_time option was provided and no read
1290+ # has yet captured atClusterTime from the server.
1291+ attr_reader :snapshot_timestamp
1292+
1293+ # Sets the snapshot time for the session. Once set, subsequent
1294+ # assignments are ignored: snapshotTime is established at most once per
1295+ # session, either from the :snapshot_time option at construction or from
1296+ # the atClusterTime returned by the first find/aggregate/distinct
1297+ # response. This keeps the property effectively read-only for callers,
1298+ # per the snapshot-sessions spec rationale.
1299+ #
12761300 # @api private
1277- attr_accessor :snapshot_timestamp
1301+ def snapshot_timestamp = ( value )
1302+ @snapshot_timestamp ||= value
1303+ end
12781304
12791305 # @return [ Integer | nil ] The deadline for the current transaction, if any.
12801306 # @api private
0 commit comments