1818
1919import logging
2020from contextlib import AbstractAsyncContextManager
21- from datetime import datetime
2221from typing import (
2322 TYPE_CHECKING ,
2423 Any ,
25- Callable ,
2624 Optional ,
27- Union ,
2825)
2926
30- from pymongo .asynchronous .command_runner import run_cursor_command
31- from pymongo .asynchronous .helpers import _handle_reauth
3227from pymongo .logger import (
3328 _SDAM_LOGGER ,
3429 _debug_log ,
3530 _SDAMStatusMessage ,
3631)
37- from pymongo .message import _GetMore , _OpMsg , _Query
38- from pymongo .response import PinnedResponse , Response
3932
4033if TYPE_CHECKING :
4134 from queue import Queue
4235 from weakref import ReferenceType
4336
4437 from bson .objectid import ObjectId
45- from pymongo .asynchronous .mongo_client import AsyncMongoClient , _MongoClientErrorHandler
38+ from pymongo .asynchronous .mongo_client import _MongoClientErrorHandler
4639 from pymongo .asynchronous .monitor import Monitor
4740 from pymongo .asynchronous .pool import AsyncConnection , Pool
4841 from pymongo .monitoring import _EventListeners
49- from pymongo .read_preferences import _ServerMode
5042 from pymongo .server_description import ServerDescription
51- from pymongo .typings import _DocumentOut
5243
5344_IS_SYNC = False
5445
55- _CURSOR_DOC_FIELDS = {"cursor" : {"firstBatch" : 1 , "nextBatch" : 1 }}
56-
5746
5847class Server :
5948 def __init__ (
@@ -118,115 +107,6 @@ def request_check(self) -> None:
118107 """Check the server's state soon."""
119108 self ._monitor .request_check ()
120109
121- async def operation_to_command (
122- self , operation : Union [_Query , _GetMore ], conn : AsyncConnection , apply_timeout : bool = False
123- ) -> tuple [dict [str , Any ], str ]:
124- cmd , db = operation .as_command (conn , apply_timeout )
125- # Support auto encryption
126- if operation .client ._encrypter and not operation .client ._encrypter ._bypass_auto_encryption :
127- cmd = await operation .client ._encrypter .encrypt ( # type: ignore[misc, assignment]
128- operation .db , cmd , operation .codec_options
129- )
130- operation .update_command (cmd )
131-
132- return cmd , db
133-
134- @_handle_reauth
135- async def run_operation (
136- self ,
137- conn : AsyncConnection ,
138- operation : Union [_Query , _GetMore ],
139- read_preference : _ServerMode ,
140- listeners : Optional [_EventListeners ],
141- unpack_res : Callable [..., list [_DocumentOut ]],
142- client : AsyncMongoClient [Any ],
143- ) -> Response :
144- """Run a _Query or _GetMore operation and return a Response object.
145-
146- This method is used only to run _Query/_GetMore operations from
147- cursors.
148- Can raise ConnectionFailure, OperationFailure, etc.
149-
150- :param conn: An AsyncConnection instance.
151- :param operation: A _Query or _GetMore object.
152- :param read_preference: The read preference to use.
153- :param listeners: Instance of _EventListeners or None.
154- :param unpack_res: A callable that decodes the wire protocol response.
155- :param client: An AsyncMongoClient instance.
156- """
157- assert listeners is not None
158- start = datetime .now ()
159-
160- use_cmd = operation .use_command (conn )
161- more_to_come = bool (operation .conn_mgr and operation .conn_mgr .more_to_come )
162- cmd , dbn = await self .operation_to_command (operation , conn , use_cmd )
163- if more_to_come :
164- request_id = 0
165- data = b""
166- max_doc_size = 0
167- else :
168- message = operation .get_message (read_preference , conn , use_cmd )
169- request_id , data , max_doc_size = self ._split_message (message )
170-
171- user_fields = _CURSOR_DOC_FIELDS if use_cmd else None
172-
173- docs , reply , duration = await run_cursor_command (
174- conn ,
175- cmd ,
176- dbn ,
177- request_id ,
178- data ,
179- client = client ,
180- session = operation .session , # type: ignore[arg-type]
181- listeners = listeners ,
182- address = conn .address ,
183- start = start ,
184- codec_options = operation .codec_options ,
185- user_fields = user_fields ,
186- command_name = operation .name ,
187- pool_opts = conn .opts ,
188- max_doc_size = max_doc_size ,
189- more_to_come = more_to_come ,
190- unpack_res = unpack_res ,
191- cursor_id = operation .cursor_id ,
192- )
193- assert reply is not None
194-
195- response : Response
196-
197- if client ._should_pin_cursor (operation .session ) or operation .exhaust : # type: ignore[arg-type]
198- conn .pin_cursor ()
199- if isinstance (reply , _OpMsg ):
200- # In OP_MSG, the server keeps sending only if the
201- # more_to_come flag is set.
202- more_to_come = reply .more_to_come
203- else :
204- # In OP_REPLY, the server keeps sending until cursor_id is 0.
205- more_to_come = bool (operation .exhaust and reply .cursor_id )
206- if operation .conn_mgr :
207- operation .conn_mgr .update_exhaust (more_to_come )
208- response = PinnedResponse (
209- data = reply ,
210- address = self ._description .address ,
211- conn = conn ,
212- duration = duration ,
213- request_id = request_id ,
214- from_command = use_cmd ,
215- docs = docs , # type: ignore[arg-type]
216- more_to_come = more_to_come ,
217- )
218- else :
219- response = Response (
220- data = reply ,
221- address = self ._description .address ,
222- duration = duration ,
223- request_id = request_id ,
224- from_command = use_cmd ,
225- docs = docs , # type: ignore[arg-type]
226- )
227-
228- return response
229-
230110 async def checkout (
231111 self , handler : Optional [_MongoClientErrorHandler ] = None
232112 ) -> AbstractAsyncContextManager [AsyncConnection ]:
@@ -245,19 +125,5 @@ def description(self, server_description: ServerDescription) -> None:
245125 def pool (self ) -> Pool :
246126 return self ._pool
247127
248- def _split_message (
249- self , message : Union [tuple [int , Any ], tuple [int , Any , int ]]
250- ) -> tuple [int , Any , int ]:
251- """Return request_id, data, max_doc_size.
252-
253- :param message: (request_id, data, max_doc_size) or (request_id, data)
254- """
255- if len (message ) == 3 :
256- return message # type: ignore[return-value]
257- else :
258- # get_more and kill_cursors messages don't include BSON documents.
259- request_id , data = message # type: ignore[misc]
260- return request_id , data , 0
261-
262128 def __repr__ (self ) -> str :
263129 return f"<{ self .__class__ .__name__ } { self ._description !r} >"
0 commit comments