@@ -857,13 +857,42 @@ def _is_writable(self):
857
857
except ConnectionFailure :
858
858
return False
859
859
860
+ def _end_sessions (self , session_ids ):
861
+ """Send endSessions command(s) with the given session ids."""
862
+ try :
863
+ # Use SocketInfo.command directly to avoid implicitly creating
864
+ # another session.
865
+ with self ._socket_for_reads (
866
+ ReadPreference .PRIMARY_PREFERRED ) as (sock_info , slave_ok ):
867
+ if not sock_info .supports_sessions :
868
+ return
869
+
870
+ for i in range (0 , len (session_ids ), common ._MAX_END_SESSIONS ):
871
+ spec = SON ([('endSessions' ,
872
+ session_ids [i :i + common ._MAX_END_SESSIONS ])])
873
+ sock_info .command (
874
+ 'admin' , spec , slave_ok = slave_ok , client = self )
875
+ except PyMongoError :
876
+ # Drivers MUST ignore any errors returned by the endSessions
877
+ # command.
878
+ pass
879
+
860
880
def close (self ):
861
- """Disconnect from MongoDB.
881
+ """Cleanup client resources and disconnect from MongoDB.
882
+
883
+ On MongoDB >= 3.6, end all server sessions created by this client by
884
+ sending one or more endSessions commands.
862
885
863
886
Close all sockets in the connection pools and stop the monitor threads.
864
887
If this instance is used again it will be automatically re-opened and
865
888
the threads restarted.
889
+
890
+ .. versionchanged:: 3.6
891
+ End all server sessions created by this client.
866
892
"""
893
+ session_ids = self ._topology .pop_all_sessions ()
894
+ if session_ids :
895
+ self ._end_sessions (session_ids )
867
896
# Run _process_periodic_tasks to send pending killCursor requests
868
897
# before closing the topology.
869
898
self ._process_periodic_tasks ()
@@ -1307,7 +1336,7 @@ def _process_periodic_tasks(self):
1307
1336
except Exception :
1308
1337
helpers ._handle_exception ()
1309
1338
1310
- def start_session (self , ** kwargs ):
1339
+ def start_session (self , causal_consistency = True ):
1311
1340
"""Start a logical session.
1312
1341
1313
1342
This method takes the same parameters as
@@ -1318,6 +1347,12 @@ def start_session(self, **kwargs):
1318
1347
if this client has been authenticated to multiple databases using the
1319
1348
deprecated method :meth:`~pymongo.database.Database.authenticate`.
1320
1349
1350
+ A :class:`~pymongo.client_session.ClientSession` may only be used with
1351
+ the MongoClient that started it.
1352
+
1353
+ :Returns:
1354
+ An instance of :class:`~pymongo.client_session.ClientSession`.
1355
+
1321
1356
.. versionadded:: 3.6
1322
1357
"""
1323
1358
# Driver Sessions Spec: "If startSession is called when multiple users
@@ -1330,8 +1365,10 @@ def start_session(self, **kwargs):
1330
1365
1331
1366
# Raises ConfigurationError if sessions are not supported.
1332
1367
server_session = self ._get_server_session ()
1333
- opts = client_session .SessionOptions (** kwargs )
1334
- return client_session .ClientSession (self , server_session , opts , authset )
1368
+ opts = client_session .SessionOptions (
1369
+ causal_consistency = causal_consistency )
1370
+ return client_session .ClientSession (
1371
+ self , server_session , opts , authset )
1335
1372
1336
1373
def _get_server_session (self ):
1337
1374
"""Internal: start or resume a _ServerSession."""
0 commit comments