@@ -358,6 +358,68 @@ def execute_insert_no_results(self, sock_info, run, op_id, acknowledged):
358358 self .collection .full_name , run .ops , True , acknowledged , concern ,
359359 not self .ordered , self .collection .codec_options , bwc )
360360
361+ def execute_op_msg_no_results (self , sock_info , generator ):
362+ """Execute write commands with OP_MSG and w=0 writeConcern, unordered.
363+ """
364+ db_name = self .collection .database .name
365+ client = self .collection .database .client
366+ listeners = client ._event_listeners
367+ op_id = _randint ()
368+
369+ if not self .current_run :
370+ self .current_run = next (generator )
371+ run = self .current_run
372+
373+ while run :
374+ cmd = SON ([(_COMMANDS [run .op_type ], self .collection .name ),
375+ ('ordered' , False ),
376+ ('writeConcern' , {'w' : 0 })])
377+ bwc = _BulkWriteContext (db_name , cmd , sock_info , op_id ,
378+ listeners , None )
379+
380+ while run .idx_offset < len (run .ops ):
381+ check_keys = run .op_type == _INSERT
382+ ops = islice (run .ops , run .idx_offset , None )
383+ # Run as many ops as possible.
384+ request_id , msg , to_send = _do_bulk_write_command (
385+ self .namespace , run .op_type , cmd , ops , check_keys ,
386+ self .collection .codec_options , bwc )
387+ if not to_send :
388+ raise InvalidOperation ("cannot do an empty bulk write" )
389+ run .idx_offset += len (to_send )
390+ # Though this isn't strictly a "legacy" write, the helper
391+ # handles publishing commands and sending our message
392+ # without receiving a result. Send 0 for max_doc_size
393+ # to disable size checking. Size checking is handled while
394+ # the documents are encoded to BSON.
395+ bwc .legacy_write (request_id , msg , 0 , False , to_send )
396+ self .current_run = run = next (generator , None )
397+
398+ def execute_command_no_results (self , sock_info , generator ):
399+ """Execute write commands with OP_MSG and w=0 WriteConcern, ordered.
400+ """
401+ full_result = {
402+ "writeErrors" : [],
403+ "writeConcernErrors" : [],
404+ "nInserted" : 0 ,
405+ "nUpserted" : 0 ,
406+ "nMatched" : 0 ,
407+ "nModified" : 0 ,
408+ "nRemoved" : 0 ,
409+ "upserted" : [],
410+ }
411+ # Ordered bulk writes have to be acknowledged so that we stop
412+ # processing at the first error, even when the application
413+ # specified unacknowledged writeConcern.
414+ write_concern = WriteConcern ()
415+ op_id = _randint ()
416+ try :
417+ self ._execute_command (
418+ generator , write_concern , None ,
419+ sock_info , op_id , False , full_result )
420+ except OperationFailure :
421+ pass
422+
361423 def execute_no_results (self , sock_info , generator ):
362424 """Execute all operations, returning no results (w=0).
363425 """
@@ -367,10 +429,17 @@ def execute_no_results(self, sock_info, generator):
367429 if self .uses_array_filters :
368430 raise ConfigurationError (
369431 'arrayFilters is unsupported for unacknowledged writes.' )
370- # Cannot have both unacknowledged write and bypass document validation.
432+ # Cannot have both unacknowledged writes and bypass document validation.
371433 if self .bypass_doc_val and sock_info .max_wire_version >= 4 :
372434 raise OperationFailure ("Cannot set bypass_document_validation with"
373435 " unacknowledged write concern" )
436+
437+ # OP_MSG
438+ if sock_info .max_wire_version > 5 :
439+ if self .ordered :
440+ return self .execute_command_no_results (sock_info , generator )
441+ return self .execute_op_msg_no_results (sock_info , generator )
442+
374443 coll = self .collection
375444 # If ordered is True we have to send GLE or use write
376445 # commands so we can abort on the first error.
0 commit comments