mongo 2.5.0.beta → 2.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - checksums.yaml.gz.sig +0 -0
 - data.tar.gz.sig +0 -0
 - data/lib/mongo/address.rb +1 -1
 - data/lib/mongo/address/unix.rb +1 -1
 - data/lib/mongo/auth/user.rb +0 -5
 - data/lib/mongo/auth/user/view.rb +4 -4
 - data/lib/mongo/bulk_write.rb +60 -32
 - data/lib/mongo/client.rb +44 -8
 - data/lib/mongo/cluster.rb +14 -12
 - data/lib/mongo/cluster/periodic_executor.rb +106 -0
 - data/lib/mongo/cluster/{cursor_reaper.rb → reapers/cursor_reaper.rb} +5 -37
 - data/lib/mongo/cluster/reapers/socket_reaper.rb +59 -0
 - data/lib/mongo/collection.rb +9 -6
 - data/lib/mongo/collection/view.rb +2 -2
 - data/lib/mongo/collection/view/builder/aggregation.rb +2 -1
 - data/lib/mongo/collection/view/builder/find_command.rb +1 -1
 - data/lib/mongo/collection/view/change_stream.rb +14 -1
 - data/lib/mongo/collection/view/map_reduce.rb +30 -13
 - data/lib/mongo/collection/view/readable.rb +5 -5
 - data/lib/mongo/collection/view/writable.rb +98 -51
 - data/lib/mongo/error.rb +3 -0
 - data/lib/mongo/error/invalid_txt_record.rb +27 -0
 - data/lib/mongo/error/invalid_uri.rb +7 -6
 - data/lib/mongo/error/mismatched_domain.rb +27 -0
 - data/lib/mongo/error/no_srv_records.rb +26 -0
 - data/lib/mongo/error/unsupported_features.rb +0 -18
 - data/lib/mongo/index/view.rb +2 -2
 - data/lib/mongo/operation.rb +1 -0
 - data/lib/mongo/operation/causally_consistent.rb +33 -0
 - data/lib/mongo/operation/commands.rb +2 -1
 - data/lib/mongo/operation/commands/aggregate.rb +2 -7
 - data/lib/mongo/operation/commands/count.rb +27 -0
 - data/lib/mongo/operation/commands/distinct.rb +27 -0
 - data/lib/mongo/operation/commands/find.rb +3 -1
 - data/lib/mongo/operation/commands/map_reduce.rb +1 -0
 - data/lib/mongo/operation/commands/parallel_scan.rb +1 -0
 - data/lib/mongo/operation/specifiable.rb +12 -0
 - data/lib/mongo/operation/uses_command_op_msg.rb +36 -5
 - data/lib/mongo/operation/write.rb +0 -5
 - data/lib/mongo/operation/write/bulk/bulkable.rb +4 -8
 - data/lib/mongo/operation/write/bulk/mergable.rb +2 -0
 - data/lib/mongo/operation/write/command/create_index.rb +19 -0
 - data/lib/mongo/operation/write/command/create_user.rb +19 -0
 - data/lib/mongo/operation/write/command/delete.rb +1 -2
 - data/lib/mongo/operation/write/command/drop_index.rb +19 -0
 - data/lib/mongo/operation/write/command/insert.rb +1 -2
 - data/lib/mongo/operation/write/command/remove_user.rb +19 -0
 - data/lib/mongo/operation/write/command/update.rb +1 -2
 - data/lib/mongo/operation/write/command/update_user.rb +19 -0
 - data/lib/mongo/operation/write/write_command_enabled.rb +1 -3
 - data/lib/mongo/protocol/compressed.rb +2 -1
 - data/lib/mongo/protocol/serializers.rb +6 -6
 - data/lib/mongo/retryable.rb +48 -5
 - data/lib/mongo/server.rb +15 -0
 - data/lib/mongo/server/connection.rb +21 -1
 - data/lib/mongo/server/connection_pool.rb +3 -0
 - data/lib/mongo/server/connection_pool/queue.rb +50 -5
 - data/lib/mongo/server/description.rb +11 -3
 - data/lib/mongo/server/description/features.rb +26 -7
 - data/lib/mongo/session.rb +133 -6
 - data/lib/mongo/session/server_session.rb +30 -0
 - data/lib/mongo/session/session_pool.rb +20 -20
 - data/lib/mongo/uri.rb +88 -44
 - data/lib/mongo/uri/srv_protocol.rb +158 -0
 - data/lib/mongo/version.rb +1 -1
 - data/lib/mongo/write_concern/normalizable.rb +12 -0
 - data/mongo.gemspec +1 -2
 - data/spec/mongo/address_spec.rb +12 -0
 - data/spec/mongo/auth/user/view_spec.rb +1 -5
 - data/spec/mongo/bulk_write_spec.rb +232 -401
 - data/spec/mongo/change_stream_examples_spec.rb +150 -0
 - data/spec/mongo/client_spec.rb +142 -2
 - data/spec/mongo/cluster/cursor_reaper_spec.rb +0 -70
 - data/spec/mongo/cluster/socket_reaper_spec.rb +32 -0
 - data/spec/mongo/cluster_spec.rb +11 -7
 - data/spec/mongo/collection/view/aggregation_spec.rb +46 -1
 - data/spec/mongo/collection/view/builder/find_command_spec.rb +15 -0
 - data/spec/mongo/collection/view/change_stream_spec.rb +79 -12
 - data/spec/mongo/collection/view/map_reduce_spec.rb +120 -4
 - data/spec/mongo/collection/view/readable_spec.rb +23 -5
 - data/spec/mongo/collection_spec.rb +292 -102
 - data/spec/mongo/command_monitoring_spec.rb +26 -32
 - data/spec/mongo/crud_spec.rb +1 -1
 - data/spec/mongo/cursor_spec.rb +2 -3
 - data/spec/mongo/database_spec.rb +30 -14
 - data/spec/mongo/dns_seedlist_discovery_spec.rb +94 -0
 - data/spec/mongo/grid/fs_bucket_spec.rb +1 -1
 - data/spec/mongo/grid/stream/write_spec.rb +1 -1
 - data/spec/mongo/index/view_spec.rb +8 -46
 - data/spec/mongo/operation/write/bulk/delete_spec.rb +2 -2
 - data/spec/mongo/operation/write/bulk/insert_spec.rb +2 -10
 - data/spec/mongo/operation/write/{create_index_spec.rb → command/create_index_spec.rb} +2 -6
 - data/spec/mongo/operation/write/command/delete_spec.rb +35 -7
 - data/spec/mongo/operation/write/{drop_index_spec.rb → command/drop_index_spec.rb} +1 -1
 - data/spec/mongo/operation/write/command/insert_spec.rb +37 -6
 - data/spec/mongo/operation/write/{remove_user_spec.rb → command/remove_user_spec.rb} +2 -6
 - data/spec/mongo/operation/write/command/update_spec.rb +34 -7
 - data/spec/mongo/operation/write/{update_user_spec.rb → command/update_user_spec.rb} +1 -1
 - data/spec/mongo/operation/write/create_user_spec.rb +1 -1
 - data/spec/mongo/operation/write/delete_spec.rb +1 -1
 - data/spec/mongo/operation/write/insert_spec.rb +2 -10
 - data/spec/mongo/operation/write/update_spec.rb +3 -15
 - data/spec/mongo/retryable_spec.rb +1 -1
 - data/spec/mongo/retryable_writes_spec.rb +815 -0
 - data/spec/mongo/server/connection_pool/queue_spec.rb +35 -2
 - data/spec/mongo/server/connection_pool_spec.rb +234 -1
 - data/spec/mongo/server/connection_spec.rb +10 -6
 - data/spec/mongo/server/description/features_spec.rb +51 -37
 - data/spec/mongo/server/description_spec.rb +6 -3
 - data/spec/mongo/server_spec.rb +87 -0
 - data/spec/mongo/session/server_session_spec.rb +43 -0
 - data/spec/mongo/session/session_pool_spec.rb +63 -27
 - data/spec/mongo/session_spec.rb +247 -0
 - data/spec/mongo/shell_examples_spec.rb +2 -2
 - data/spec/mongo/uri/srv_protocol_spec.rb +933 -0
 - data/spec/mongo/uri_spec.rb +42 -3
 - data/spec/mongo/write_concern/acknowledged_spec.rb +11 -0
 - data/spec/mongo/write_concern/unacknowledged_spec.rb +11 -0
 - data/spec/spec_helper.rb +11 -25
 - data/spec/support/authorization.rb +2 -1
 - data/spec/support/connection_string.rb +8 -4
 - data/spec/support/crud.rb +38 -24
 - data/spec/support/crud/write.rb +30 -3
 - data/spec/support/crud_tests/read/aggregate-out.yml +21 -0
 - data/spec/support/crud_tests/write/bulkWrite-arrayFilters.yml +44 -0
 - data/spec/support/crud_tests/write/findOneAndUpdate-arrayFilters.yml +1 -1
 - data/spec/support/crud_tests/write/insertMany.yml +1 -3
 - data/spec/support/crud_tests/write/replaceOne.yml +1 -1
 - data/spec/support/crud_tests/write/updateMany-arrayFilters.yml +1 -1
 - data/spec/support/crud_tests/write/updateOne-arrayFilters.yml +1 -1
 - data/spec/support/dns_seedlist_discovery_tests/longer-parent-in-return.yml +11 -0
 - data/spec/support/dns_seedlist_discovery_tests/misformatted-option.yml +5 -0
 - data/spec/support/dns_seedlist_discovery_tests/no-results.yml +5 -0
 - data/spec/support/dns_seedlist_discovery_tests/not-enough-parts.yml +5 -0
 - data/spec/support/dns_seedlist_discovery_tests/one-result-default-port.yml +10 -0
 - data/spec/support/dns_seedlist_discovery_tests/one-txt-record-multiple-strings.yml +10 -0
 - data/spec/support/dns_seedlist_discovery_tests/one-txt-record.yml +11 -0
 - data/spec/support/dns_seedlist_discovery_tests/parent-part-mismatch1.yml +5 -0
 - data/spec/support/dns_seedlist_discovery_tests/parent-part-mismatch2.yml +5 -0
 - data/spec/support/dns_seedlist_discovery_tests/parent-part-mismatch3.yml +5 -0
 - data/spec/support/dns_seedlist_discovery_tests/parent-part-mismatch4.yml +5 -0
 - data/spec/support/dns_seedlist_discovery_tests/parent-part-mismatch5.yml +5 -0
 - data/spec/support/dns_seedlist_discovery_tests/returned-parent-too-short.yml +5 -0
 - data/spec/support/dns_seedlist_discovery_tests/returned-parent-wrong.yml +5 -0
 - data/spec/support/dns_seedlist_discovery_tests/two-results-default-port.yml +11 -0
 - data/spec/support/dns_seedlist_discovery_tests/two-results-nonstandard-port.yml +11 -0
 - data/spec/support/dns_seedlist_discovery_tests/two-txt-records.yml +5 -0
 - data/spec/support/dns_seedlist_discovery_tests/txt-record-not-allowed-option.yml +5 -0
 - data/spec/support/dns_seedlist_discovery_tests/txt-record-with-overridden-ssl-option.yml +11 -0
 - data/spec/support/dns_seedlist_discovery_tests/txt-record-with-overridden-uri-option.yml +11 -0
 - data/spec/support/dns_seedlist_discovery_tests/txt-record-with-unallowed-option.yml +5 -0
 - data/spec/support/dns_seedlist_discovery_tests/uri-with-port.yml +5 -0
 - data/spec/support/dns_seedlist_discovery_tests/uri-with-two-hosts.yml +5 -0
 - data/spec/support/retryable_writes_tests/bulkWrite.yml +305 -0
 - data/spec/support/retryable_writes_tests/deleteOne.yml +51 -0
 - data/spec/support/retryable_writes_tests/findOneAndDelete.yml +52 -0
 - data/spec/support/retryable_writes_tests/findOneAndReplace.yml +57 -0
 - data/spec/support/retryable_writes_tests/findOneAndUpdate.yml +56 -0
 - data/spec/support/retryable_writes_tests/insertMany.yml +72 -0
 - data/spec/support/retryable_writes_tests/insertOne.yml +55 -0
 - data/spec/support/retryable_writes_tests/replaceOne.yml +60 -0
 - data/spec/support/retryable_writes_tests/updateOne.yml +120 -0
 - data/spec/support/shared/session.rb +525 -24
 - metadata +437 -350
 - metadata.gz.sig +0 -0
 - data/lib/mongo/operation/commands/user_query.rb +0 -72
 - data/lib/mongo/operation/write/create_index.rb +0 -67
 - data/lib/mongo/operation/write/create_user.rb +0 -50
 - data/lib/mongo/operation/write/drop_index.rb +0 -63
 - data/lib/mongo/operation/write/remove_user.rb +0 -48
 - data/lib/mongo/operation/write/update_user.rb +0 -50
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA1:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: 4a0c8476badc0a3215c3e04955d182d0f5d8eff0
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 8e22da76ade8734b4a58a9fbac4aa0524825800e
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: cc6f598c936f2aff4eea3fa9d9eb00eea905912c1d2c587d6b307f3d97655d29bd5fd12dd02a6548a384fe04e82b169ff22c5d9ed7db77ec74e7073793345d27
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: 118a7e1f0942d35672138d6a3ab0d1b3967122d14344fe7cc3645d1a3b511dfd7cf6b05ad547e2b04ee19230dd30f8978f004bddec7952c230183948e8180ceb
         
     | 
    
        checksums.yaml.gz.sig
    CHANGED
    
    | 
         Binary file 
     | 
    
        data.tar.gz.sig
    CHANGED
    
    | 
         Binary file 
     | 
    
        data/lib/mongo/address.rb
    CHANGED
    
    | 
         @@ -185,7 +185,7 @@ module Mongo 
     | 
|
| 
       185 
185 
     | 
    
         
             
                  error = nil
         
     | 
| 
       186 
186 
     | 
    
         
             
                  ::Socket.getaddrinfo(host, nil, family, ::Socket::SOCK_STREAM).each do |info|
         
     | 
| 
       187 
187 
     | 
    
         
             
                    begin
         
     | 
| 
       188 
     | 
    
         
            -
                      res = FAMILY_MAP[info[4]].new( 
     | 
| 
      
 188 
     | 
    
         
            +
                      res = FAMILY_MAP[info[4]].new(host, port, host)
         
     | 
| 
       189 
189 
     | 
    
         
             
                      res.socket(connect_timeout, ssl_options).connect!(connect_timeout).close
         
     | 
| 
       190 
190 
     | 
    
         
             
                      return res
         
     | 
| 
       191 
191 
     | 
    
         
             
                    rescue IOError, SystemCallError, Error::SocketTimeoutError, Error::SocketError => e
         
     | 
    
        data/lib/mongo/address/unix.rb
    CHANGED
    
    | 
         @@ -62,7 +62,7 @@ module Mongo 
     | 
|
| 
       62 
62 
     | 
    
         
             
                  # @example Get a Unix socket.
         
     | 
| 
       63 
63 
     | 
    
         
             
                  #   address.socket(5)
         
     | 
| 
       64 
64 
     | 
    
         
             
                  #
         
     | 
| 
       65 
     | 
    
         
            -
                  # @param [ Float ]  
     | 
| 
      
 65 
     | 
    
         
            +
                  # @param [ Float ] socket_timeout The socket timeout.
         
     | 
| 
       66 
66 
     | 
    
         
             
                  # @param [ Hash ] ssl_options SSL options - ignored.
         
     | 
| 
       67 
67 
     | 
    
         
             
                  #
         
     | 
| 
       68 
68 
     | 
    
         
             
                  # @return [ Pool::Socket::Unix ] The socket.
         
     | 
    
        data/lib/mongo/auth/user.rb
    CHANGED
    
    | 
         @@ -22,11 +22,6 @@ module Mongo 
     | 
|
| 
       22 
22 
     | 
    
         
             
                # @since 2.0.0
         
     | 
| 
       23 
23 
     | 
    
         
             
                class User
         
     | 
| 
       24 
24 
     | 
    
         | 
| 
       25 
     | 
    
         
            -
                  # The users collection for the database.
         
     | 
| 
       26 
     | 
    
         
            -
                  #
         
     | 
| 
       27 
     | 
    
         
            -
                  # @since 2.0.0
         
     | 
| 
       28 
     | 
    
         
            -
                  COLLECTION = 'system.users'.freeze
         
     | 
| 
       29 
     | 
    
         
            -
             
     | 
| 
       30 
25 
     | 
    
         
             
                  # @return [ String ] The authorization source, either a database or
         
     | 
| 
       31 
26 
     | 
    
         
             
                  #   external name.
         
     | 
| 
       32 
27 
     | 
    
         
             
                  attr_reader :auth_source
         
     | 
    
        data/lib/mongo/auth/user/view.rb
    CHANGED
    
    | 
         @@ -44,7 +44,7 @@ module Mongo 
     | 
|
| 
       44 
44 
     | 
    
         
             
                    def create(user_or_name, options = {})
         
     | 
| 
       45 
45 
     | 
    
         
             
                      user = generate(user_or_name, options)
         
     | 
| 
       46 
46 
     | 
    
         
             
                      client.send(:with_session, options) do |session|
         
     | 
| 
       47 
     | 
    
         
            -
                        Operation::Write::CreateUser.new(
         
     | 
| 
      
 47 
     | 
    
         
            +
                        Operation::Write::Command::CreateUser.new(
         
     | 
| 
       48 
48 
     | 
    
         
             
                          user: user,
         
     | 
| 
       49 
49 
     | 
    
         
             
                          db_name: database.name,
         
     | 
| 
       50 
50 
     | 
    
         
             
                          session: session
         
     | 
| 
         @@ -79,7 +79,7 @@ module Mongo 
     | 
|
| 
       79 
79 
     | 
    
         
             
                    # @since 2.0.0
         
     | 
| 
       80 
80 
     | 
    
         
             
                    def remove(name, options = {})
         
     | 
| 
       81 
81 
     | 
    
         
             
                      client.send(:with_session, options) do |session|
         
     | 
| 
       82 
     | 
    
         
            -
                        Operation::Write::RemoveUser.new(
         
     | 
| 
      
 82 
     | 
    
         
            +
                        Operation::Write::Command::RemoveUser.new(
         
     | 
| 
       83 
83 
     | 
    
         
             
                          user_name: name,
         
     | 
| 
       84 
84 
     | 
    
         
             
                          db_name: database.name,
         
     | 
| 
       85 
85 
     | 
    
         
             
                          session: session
         
     | 
| 
         @@ -103,7 +103,7 @@ module Mongo 
     | 
|
| 
       103 
103 
     | 
    
         
             
                    def update(user_or_name, options = {})
         
     | 
| 
       104 
104 
     | 
    
         
             
                      client.send(:with_session, options) do |session|
         
     | 
| 
       105 
105 
     | 
    
         
             
                        user = generate(user_or_name, options)
         
     | 
| 
       106 
     | 
    
         
            -
                        Operation::Write::UpdateUser.new(
         
     | 
| 
      
 106 
     | 
    
         
            +
                        Operation::Write::Command::UpdateUser.new(
         
     | 
| 
       107 
107 
     | 
    
         
             
                          user: user,
         
     | 
| 
       108 
108 
     | 
    
         
             
                          db_name: database.name,
         
     | 
| 
       109 
109 
     | 
    
         
             
                          session: session
         
     | 
| 
         @@ -132,7 +132,7 @@ module Mongo 
     | 
|
| 
       132 
132 
     | 
    
         | 
| 
       133 
133 
     | 
    
         
             
                    def user_query(name, options = {})
         
     | 
| 
       134 
134 
     | 
    
         
             
                      client.send(:with_session, options) do |session|
         
     | 
| 
       135 
     | 
    
         
            -
                        Operation::Commands:: 
     | 
| 
      
 135 
     | 
    
         
            +
                        Operation::Commands::UsersInfo.new(
         
     | 
| 
       136 
136 
     | 
    
         
             
                          user_name: name,
         
     | 
| 
       137 
137 
     | 
    
         
             
                          db_name: database.name,
         
     | 
| 
       138 
138 
     | 
    
         
             
                          session: session
         
     | 
    
        data/lib/mongo/bulk_write.rb
    CHANGED
    
    | 
         @@ -53,22 +53,31 @@ module Mongo 
     | 
|
| 
       53 
53 
     | 
    
         
             
                def execute
         
     | 
| 
       54 
54 
     | 
    
         
             
                  operation_id = Monitoring.next_operation_id
         
     | 
| 
       55 
55 
     | 
    
         
             
                  result_combiner = ResultCombiner.new
         
     | 
| 
      
 56 
     | 
    
         
            +
                  operations = op_combiner.combine
         
     | 
| 
       56 
57 
     | 
    
         | 
| 
       57 
58 
     | 
    
         
             
                  client.send(:with_session, @options) do |session|
         
     | 
| 
       58 
     | 
    
         
            -
                     
     | 
| 
       59 
     | 
    
         
            -
                       
     | 
| 
       60 
     | 
    
         
            -
             
     | 
| 
       61 
     | 
    
         
            -
             
     | 
| 
       62 
     | 
    
         
            -
             
     | 
| 
       63 
     | 
    
         
            -
             
     | 
| 
       64 
     | 
    
         
            -
             
     | 
| 
       65 
     | 
    
         
            -
             
     | 
| 
       66 
     | 
    
         
            -
             
     | 
| 
       67 
     | 
    
         
            -
             
     | 
| 
       68 
     | 
    
         
            -
             
     | 
| 
       69 
     | 
    
         
            -
             
     | 
| 
       70 
     | 
    
         
            -
             
     | 
| 
       71 
     | 
    
         
            -
                         
     | 
| 
      
 59 
     | 
    
         
            +
                    operations.each do |operation|
         
     | 
| 
      
 60 
     | 
    
         
            +
                      if single_statement?(operation)
         
     | 
| 
      
 61 
     | 
    
         
            +
                        write_with_retry(session, write_concern) do |server, txn_num|
         
     | 
| 
      
 62 
     | 
    
         
            +
                          execute_operation(
         
     | 
| 
      
 63 
     | 
    
         
            +
                              operation.keys.first,
         
     | 
| 
      
 64 
     | 
    
         
            +
                              operation.values.first,
         
     | 
| 
      
 65 
     | 
    
         
            +
                              server,
         
     | 
| 
      
 66 
     | 
    
         
            +
                              operation_id,
         
     | 
| 
      
 67 
     | 
    
         
            +
                              result_combiner,
         
     | 
| 
      
 68 
     | 
    
         
            +
                              session,
         
     | 
| 
      
 69 
     | 
    
         
            +
                              txn_num)
         
     | 
| 
      
 70 
     | 
    
         
            +
                        end
         
     | 
| 
      
 71 
     | 
    
         
            +
                      else
         
     | 
| 
      
 72 
     | 
    
         
            +
                        legacy_write_with_retry do |server|
         
     | 
| 
      
 73 
     | 
    
         
            +
                          execute_operation(
         
     | 
| 
      
 74 
     | 
    
         
            +
                              operation.keys.first,
         
     | 
| 
      
 75 
     | 
    
         
            +
                              operation.values.first,
         
     | 
| 
      
 76 
     | 
    
         
            +
                              server,
         
     | 
| 
      
 77 
     | 
    
         
            +
                              operation_id,
         
     | 
| 
      
 78 
     | 
    
         
            +
                              result_combiner,
         
     | 
| 
      
 79 
     | 
    
         
            +
                              session)
         
     | 
| 
      
 80 
     | 
    
         
            +
                        end
         
     | 
| 
       72 
81 
     | 
    
         
             
                      end
         
     | 
| 
       73 
82 
     | 
    
         
             
                    end
         
     | 
| 
       74 
83 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -137,6 +146,14 @@ module Mongo 
     | 
|
| 
       137 
146 
     | 
    
         | 
| 
       138 
147 
     | 
    
         
             
                private
         
     | 
| 
       139 
148 
     | 
    
         | 
| 
      
 149 
     | 
    
         
            +
                SINGLE_STATEMENT_OPS = [ :delete_one,
         
     | 
| 
      
 150 
     | 
    
         
            +
                                         :update_one,
         
     | 
| 
      
 151 
     | 
    
         
            +
                                         :insert_one ].freeze
         
     | 
| 
      
 152 
     | 
    
         
            +
             
     | 
| 
      
 153 
     | 
    
         
            +
                def single_statement?(operation)
         
     | 
| 
      
 154 
     | 
    
         
            +
                  SINGLE_STATEMENT_OPS.include?(operation.keys.first)
         
     | 
| 
      
 155 
     | 
    
         
            +
                end
         
     | 
| 
      
 156 
     | 
    
         
            +
             
     | 
| 
       140 
157 
     | 
    
         
             
                def base_spec(operation_id, session)
         
     | 
| 
       141 
158 
     | 
    
         
             
                  {
         
     | 
| 
       142 
159 
     | 
    
         
             
                    :db_name => database.name,
         
     | 
| 
         @@ -151,16 +168,18 @@ module Mongo 
     | 
|
| 
       151 
168 
     | 
    
         
             
                  }
         
     | 
| 
       152 
169 
     | 
    
         
             
                end
         
     | 
| 
       153 
170 
     | 
    
         | 
| 
       154 
     | 
    
         
            -
                def execute_operation(name, values, server, operation_id, combiner, session)
         
     | 
| 
      
 171 
     | 
    
         
            +
                def execute_operation(name, values, server, operation_id, combiner, session, txn_num = nil)
         
     | 
| 
      
 172 
     | 
    
         
            +
                  raise Error::UnsupportedCollation.new if op_combiner.has_collation && !server.features.collation_enabled?
         
     | 
| 
      
 173 
     | 
    
         
            +
                  raise Error::UnsupportedArrayFilters.new if op_combiner.has_array_filters && !server.features.array_filters_enabled?
         
     | 
| 
       155 
174 
     | 
    
         
             
                  begin
         
     | 
| 
       156 
175 
     | 
    
         
             
                    if values.size > server.max_write_batch_size
         
     | 
| 
       157 
     | 
    
         
            -
                      split_execute(name, values, server, operation_id, combiner, session)
         
     | 
| 
      
 176 
     | 
    
         
            +
                      split_execute(name, values, server, operation_id, combiner, session, txn_num)
         
     | 
| 
       158 
177 
     | 
    
         
             
                    else
         
     | 
| 
       159 
     | 
    
         
            -
                      combiner.combine!(send(name, values, server, operation_id, session), values.size)
         
     | 
| 
      
 178 
     | 
    
         
            +
                      combiner.combine!(send(name, values, server, operation_id, session, txn_num), values.size)
         
     | 
| 
       160 
179 
     | 
    
         
             
                    end
         
     | 
| 
       161 
180 
     | 
    
         
             
                  rescue Error::MaxBSONSize, Error::MaxMessageSize => e
         
     | 
| 
       162 
181 
     | 
    
         
             
                    raise e if values.size <= 1
         
     | 
| 
       163 
     | 
    
         
            -
                    split_execute(name, values, server, operation_id, combiner, session)
         
     | 
| 
      
 182 
     | 
    
         
            +
                    split_execute(name, values, server, operation_id, combiner, session, txn_num)
         
     | 
| 
       164 
183 
     | 
    
         
             
                  end
         
     | 
| 
       165 
184 
     | 
    
         
             
                end
         
     | 
| 
       166 
185 
     | 
    
         | 
| 
         @@ -168,34 +187,43 @@ module Mongo 
     | 
|
| 
       168 
187 
     | 
    
         
             
                  @op_combiner ||= ordered? ? OrderedCombiner.new(requests) : UnorderedCombiner.new(requests)
         
     | 
| 
       169 
188 
     | 
    
         
             
                end
         
     | 
| 
       170 
189 
     | 
    
         | 
| 
       171 
     | 
    
         
            -
                def split_execute(name, values, server, operation_id, combiner, session)
         
     | 
| 
       172 
     | 
    
         
            -
                  execute_operation(name, values.shift(values.size / 2), server, operation_id, combiner, session)
         
     | 
| 
       173 
     | 
    
         
            -
             
     | 
| 
      
 190 
     | 
    
         
            +
                def split_execute(name, values, server, operation_id, combiner, session, txn_num)
         
     | 
| 
      
 191 
     | 
    
         
            +
                  execute_operation(name, values.shift(values.size / 2), server, operation_id, combiner, session, txn_num)
         
     | 
| 
      
 192 
     | 
    
         
            +
             
     | 
| 
      
 193 
     | 
    
         
            +
                  txn_num = session.next_txn_num if txn_num
         
     | 
| 
      
 194 
     | 
    
         
            +
                  execute_operation(name, values, server, operation_id, combiner, session, txn_num)
         
     | 
| 
       174 
195 
     | 
    
         
             
                end
         
     | 
| 
       175 
196 
     | 
    
         | 
| 
       176 
     | 
    
         
            -
                def  
     | 
| 
      
 197 
     | 
    
         
            +
                def delete_one(documents, server, operation_id, session, txn_num)
         
     | 
| 
       177 
198 
     | 
    
         
             
                  Operation::Write::Bulk::Delete.new(
         
     | 
| 
       178 
     | 
    
         
            -
                    base_spec(operation_id, session).merge(:deletes => documents)
         
     | 
| 
      
 199 
     | 
    
         
            +
                    base_spec(operation_id, session).merge(:deletes => documents, :txn_num => txn_num)
         
     | 
| 
      
 200 
     | 
    
         
            +
                  ).execute(server)
         
     | 
| 
      
 201 
     | 
    
         
            +
                end
         
     | 
| 
      
 202 
     | 
    
         
            +
             
     | 
| 
      
 203 
     | 
    
         
            +
                def delete_many(documents, server, operation_id, session, txn_num)
         
     | 
| 
      
 204 
     | 
    
         
            +
                  Operation::Write::Bulk::Delete.new(
         
     | 
| 
      
 205 
     | 
    
         
            +
                      base_spec(operation_id, session).merge(:deletes => documents)
         
     | 
| 
       179 
206 
     | 
    
         
             
                  ).execute(server)
         
     | 
| 
       180 
207 
     | 
    
         
             
                end
         
     | 
| 
       181 
208 
     | 
    
         | 
| 
       182 
     | 
    
         
            -
                alias :delete_one :delete
         
     | 
| 
       183 
     | 
    
         
            -
                alias :delete_many :delete
         
     | 
| 
       184 
209 
     | 
    
         | 
| 
       185 
     | 
    
         
            -
                def insert_one(documents, server, operation_id, session)
         
     | 
| 
      
 210 
     | 
    
         
            +
                def insert_one(documents, server, operation_id, session, txn_num)
         
     | 
| 
       186 
211 
     | 
    
         
             
                  Operation::Write::Bulk::Insert.new(
         
     | 
| 
       187 
     | 
    
         
            -
                    base_spec(operation_id, session).merge(:documents => documents)
         
     | 
| 
      
 212 
     | 
    
         
            +
                    base_spec(operation_id, session).merge(:documents => documents, :txn_num => txn_num)
         
     | 
| 
       188 
213 
     | 
    
         
             
                  ).execute(server)
         
     | 
| 
       189 
214 
     | 
    
         
             
                end
         
     | 
| 
       190 
215 
     | 
    
         | 
| 
       191 
     | 
    
         
            -
                def  
     | 
| 
      
 216 
     | 
    
         
            +
                def update_one(documents, server, operation_id, session, txn_num)
         
     | 
| 
       192 
217 
     | 
    
         
             
                  Operation::Write::Bulk::Update.new(
         
     | 
| 
       193 
     | 
    
         
            -
                    base_spec(operation_id, session).merge(:updates => documents)
         
     | 
| 
      
 218 
     | 
    
         
            +
                    base_spec(operation_id, session).merge(:updates => documents, :txn_num => txn_num)
         
     | 
| 
       194 
219 
     | 
    
         
             
                  ).execute(server)
         
     | 
| 
       195 
220 
     | 
    
         
             
                end
         
     | 
| 
      
 221 
     | 
    
         
            +
                alias :replace_one :update_one
         
     | 
| 
       196 
222 
     | 
    
         | 
| 
       197 
     | 
    
         
            -
                 
     | 
| 
       198 
     | 
    
         
            -
             
     | 
| 
       199 
     | 
    
         
            -
             
     | 
| 
      
 223 
     | 
    
         
            +
                def update_many(documents, server, operation_id, session, txn_num)
         
     | 
| 
      
 224 
     | 
    
         
            +
                  Operation::Write::Bulk::Update.new(
         
     | 
| 
      
 225 
     | 
    
         
            +
                      base_spec(operation_id, session).merge(:updates => documents)
         
     | 
| 
      
 226 
     | 
    
         
            +
                  ).execute(server)
         
     | 
| 
      
 227 
     | 
    
         
            +
                end
         
     | 
| 
       200 
228 
     | 
    
         
             
              end
         
     | 
| 
       201 
229 
     | 
    
         
             
            end
         
     | 
    
        data/lib/mongo/client.rb
    CHANGED
    
    | 
         @@ -44,6 +44,7 @@ module Mongo 
     | 
|
| 
       44 
44 
     | 
    
         
             
                  :id_generator,
         
     | 
| 
       45 
45 
     | 
    
         
             
                  :local_threshold,
         
     | 
| 
       46 
46 
     | 
    
         
             
                  :logger,
         
     | 
| 
      
 47 
     | 
    
         
            +
                  :max_idle_time,
         
     | 
| 
       47 
48 
     | 
    
         
             
                  :max_pool_size,
         
     | 
| 
       48 
49 
     | 
    
         
             
                  :max_read_retries,
         
     | 
| 
       49 
50 
     | 
    
         
             
                  :min_pool_size,
         
     | 
| 
         @@ -53,6 +54,7 @@ module Mongo 
     | 
|
| 
       53 
54 
     | 
    
         
             
                  :read,
         
     | 
| 
       54 
55 
     | 
    
         
             
                  :read_retry_interval,
         
     | 
| 
       55 
56 
     | 
    
         
             
                  :replica_set,
         
     | 
| 
      
 57 
     | 
    
         
            +
                  :retry_writes,
         
     | 
| 
       56 
58 
     | 
    
         
             
                  :server_selection_timeout,
         
     | 
| 
       57 
59 
     | 
    
         
             
                  :socket_timeout,
         
     | 
| 
       58 
60 
     | 
    
         
             
                  :ssl,
         
     | 
| 
         @@ -166,6 +168,8 @@ module Mongo 
     | 
|
| 
       166 
168 
     | 
    
         
             
                # @option options [ Integer ] :server_selection_timeout The timeout in seconds
         
     | 
| 
       167 
169 
     | 
    
         
             
                #   for selecting a server for an operation.
         
     | 
| 
       168 
170 
     | 
    
         
             
                # @option options [ String ] :password The user's password.
         
     | 
| 
      
 171 
     | 
    
         
            +
                # @option options [ Integer ] :max_idle_time The maximum seconds a socket can remain idle
         
     | 
| 
      
 172 
     | 
    
         
            +
                #   since it has been checked in to the pool.
         
     | 
| 
       169 
173 
     | 
    
         
             
                # @option options [ Integer ] :max_pool_size The maximum size of the
         
     | 
| 
       170 
174 
     | 
    
         
             
                #   connection pool.
         
     | 
| 
       171 
175 
     | 
    
         
             
                # @option options [ Integer ] :min_pool_size The minimum size of the
         
     | 
| 
         @@ -174,8 +178,9 @@ module Mongo 
     | 
|
| 
       174 
178 
     | 
    
         
             
                #   seconds, in the connection pool for a connection to be checked in.
         
     | 
| 
       175 
179 
     | 
    
         
             
                # @option options [ Float ] :connect_timeout The timeout, in seconds, to
         
     | 
| 
       176 
180 
     | 
    
         
             
                #   attempt a connection.
         
     | 
| 
       177 
     | 
    
         
            -
                # @option options [ Array<String> ] :compressors  
     | 
| 
       178 
     | 
    
         
            -
                # 
     | 
| 
      
 181 
     | 
    
         
            +
                # @option options [ Array<String> ] :compressors A list of potential compressors to use, in order of preference.
         
     | 
| 
      
 182 
     | 
    
         
            +
                #  The driver chooses the first compressor that is also supported by the server. Currently the driver only
         
     | 
| 
      
 183 
     | 
    
         
            +
                #   supports 'zlib'.
         
     | 
| 
       179 
184 
     | 
    
         
             
                # @option options [ Hash ] :read The read preference options. They consist of a
         
     | 
| 
       180 
185 
     | 
    
         
             
                #   mode specified as a symbol, an array of hashes known as tag_sets,
         
     | 
| 
       181 
186 
     | 
    
         
             
                #   and local_threshold.
         
     | 
| 
         @@ -236,6 +241,10 @@ module Mongo 
     | 
|
| 
       236 
241 
     | 
    
         
             
                #   mongod logs upon establishing a connection in server versions >= 3.4.
         
     | 
| 
       237 
242 
     | 
    
         
             
                # @option options [ String ] :platform Platform information to include in the
         
     | 
| 
       238 
243 
     | 
    
         
             
                #   metadata printed to the mongod logs upon establishing a connection in server versions >= 3.4.
         
     | 
| 
      
 244 
     | 
    
         
            +
                # @option options [ Integer ] :zlib_compression_level The Zlib compression level to use, if using compression.
         
     | 
| 
      
 245 
     | 
    
         
            +
                #   See Ruby's Zlib module for valid levels.
         
     | 
| 
      
 246 
     | 
    
         
            +
                # @option options [ true, false ] :retry_writes Retry writes once when connected to a replica set
         
     | 
| 
      
 247 
     | 
    
         
            +
                #   or sharded cluster versions 3.6 and up.
         
     | 
| 
       239 
248 
     | 
    
         
             
                #
         
     | 
| 
       240 
249 
     | 
    
         
             
                # @since 2.0.0
         
     | 
| 
       241 
250 
     | 
    
         
             
                def initialize(addresses_or_uri, options = Options::Redacted.new)
         
     | 
| 
         @@ -387,11 +396,14 @@ module Mongo 
     | 
|
| 
       387 
396 
     | 
    
         
             
                # @example Get the database names.
         
     | 
| 
       388 
397 
     | 
    
         
             
                #   client.database_names
         
     | 
| 
       389 
398 
     | 
    
         
             
                #
         
     | 
| 
      
 399 
     | 
    
         
            +
                # @param [ Hash ] filter The filter criteria for getting a list of databases.
         
     | 
| 
      
 400 
     | 
    
         
            +
                # @param [ Hash ] opts The command options.
         
     | 
| 
      
 401 
     | 
    
         
            +
                #
         
     | 
| 
       390 
402 
     | 
    
         
             
                # @return [ Array<String> ] The names of the databases.
         
     | 
| 
       391 
403 
     | 
    
         
             
                #
         
     | 
| 
       392 
404 
     | 
    
         
             
                # @since 2.0.5
         
     | 
| 
       393 
     | 
    
         
            -
                def database_names
         
     | 
| 
       394 
     | 
    
         
            -
                  list_databases.collect{ |info| info[Database::NAME] }
         
     | 
| 
      
 405 
     | 
    
         
            +
                def database_names(filter = {}, opts = {})
         
     | 
| 
      
 406 
     | 
    
         
            +
                  list_databases(filter, true, opts).collect{ |info| info[Database::NAME] }
         
     | 
| 
       395 
407 
     | 
    
         
             
                end
         
     | 
| 
       396 
408 
     | 
    
         | 
| 
       397 
409 
     | 
    
         
             
                # Get info for each database.
         
     | 
| 
         @@ -399,11 +411,35 @@ module Mongo 
     | 
|
| 
       399 
411 
     | 
    
         
             
                # @example Get the info for each database.
         
     | 
| 
       400 
412 
     | 
    
         
             
                #   client.list_databases
         
     | 
| 
       401 
413 
     | 
    
         
             
                #
         
     | 
| 
      
 414 
     | 
    
         
            +
                # @param [ Hash ] filter The filter criteria for getting a list of databases.
         
     | 
| 
      
 415 
     | 
    
         
            +
                # @param [ true, false ] name_only Whether to only return each database name without full metadata.
         
     | 
| 
      
 416 
     | 
    
         
            +
                # @param [ Hash ] opts The command options.
         
     | 
| 
      
 417 
     | 
    
         
            +
                #
         
     | 
| 
       402 
418 
     | 
    
         
             
                # @return [ Array<Hash> ] The info for each database.
         
     | 
| 
       403 
419 
     | 
    
         
             
                #
         
     | 
| 
       404 
420 
     | 
    
         
             
                # @since 2.0.5
         
     | 
| 
       405 
     | 
    
         
            -
                def list_databases
         
     | 
| 
       406 
     | 
    
         
            -
                   
     | 
| 
      
 421 
     | 
    
         
            +
                def list_databases(filter = {}, name_only = false, opts = {})
         
     | 
| 
      
 422 
     | 
    
         
            +
                  cmd = { listDatabases: 1 }
         
     | 
| 
      
 423 
     | 
    
         
            +
                  cmd[:nameOnly] = !!name_only
         
     | 
| 
      
 424 
     | 
    
         
            +
                  cmd[:filter] = filter unless filter.empty?
         
     | 
| 
      
 425 
     | 
    
         
            +
                  use(Database::ADMIN).command(cmd, opts).first[Database::DATABASES]
         
     | 
| 
      
 426 
     | 
    
         
            +
                end
         
     | 
| 
      
 427 
     | 
    
         
            +
             
     | 
| 
      
 428 
     | 
    
         
            +
                # Returns a list of Mongo::Database objects.
         
     | 
| 
      
 429 
     | 
    
         
            +
                #
         
     | 
| 
      
 430 
     | 
    
         
            +
                # @example Get a list of Mongo::Database objects.
         
     | 
| 
      
 431 
     | 
    
         
            +
                #   client.list_mongo_databases
         
     | 
| 
      
 432 
     | 
    
         
            +
                #
         
     | 
| 
      
 433 
     | 
    
         
            +
                # @param [ Hash ] filter The filter criteria for getting a list of databases.
         
     | 
| 
      
 434 
     | 
    
         
            +
                # @param [ Hash ] opts The command options.
         
     | 
| 
      
 435 
     | 
    
         
            +
                #
         
     | 
| 
      
 436 
     | 
    
         
            +
                # @return [ Array<Mongo::Database> ] The list of database objects.
         
     | 
| 
      
 437 
     | 
    
         
            +
                #
         
     | 
| 
      
 438 
     | 
    
         
            +
                # @since 2.5.0
         
     | 
| 
      
 439 
     | 
    
         
            +
                def list_mongo_databases(filter = {}, opts = {})
         
     | 
| 
      
 440 
     | 
    
         
            +
                  database_names(filter, opts).collect do |name|
         
     | 
| 
      
 441 
     | 
    
         
            +
                    Database.new(self, name, options)
         
     | 
| 
      
 442 
     | 
    
         
            +
                  end
         
     | 
| 
       407 
443 
     | 
    
         
             
                end
         
     | 
| 
       408 
444 
     | 
    
         | 
| 
       409 
445 
     | 
    
         
             
                # Start a session.
         
     | 
| 
         @@ -451,7 +487,7 @@ module Mongo 
     | 
|
| 
       451 
487 
     | 
    
         
             
                end
         
     | 
| 
       452 
488 
     | 
    
         | 
| 
       453 
489 
     | 
    
         
             
                def sessions_supported?
         
     | 
| 
       454 
     | 
    
         
            -
                  if cluster.servers.empty?
         
     | 
| 
      
 490 
     | 
    
         
            +
                  if cluster.servers.empty? && !cluster.topology.single?
         
     | 
| 
       455 
491 
     | 
    
         
             
                    ServerSelector.get(mode: :primary_preferred).select_server(cluster)
         
     | 
| 
       456 
492 
     | 
    
         
             
                  end
         
     | 
| 
       457 
493 
     | 
    
         
             
                  !!logical_session_timeout
         
     | 
| 
         @@ -465,7 +501,7 @@ module Mongo 
     | 
|
| 
       465 
501 
     | 
    
         
             
                end
         
     | 
| 
       466 
502 
     | 
    
         | 
| 
       467 
503 
     | 
    
         
             
                def create_from_uri(connection_string, opts = Options::Redacted.new)
         
     | 
| 
       468 
     | 
    
         
            -
                  uri = URI. 
     | 
| 
      
 504 
     | 
    
         
            +
                  uri = URI.get(connection_string, opts)
         
     | 
| 
       469 
505 
     | 
    
         
             
                  @options = validate_options!(Database::DEFAULT_OPTIONS.merge(uri.client_options.merge(opts))).freeze
         
     | 
| 
       470 
506 
     | 
    
         
             
                  @cluster = Cluster.new(uri.servers, @monitoring, options)
         
     | 
| 
       471 
507 
     | 
    
         
             
                  @database = Database.new(self, options[:database], options)
         
     | 
    
        data/lib/mongo/cluster.rb
    CHANGED
    
    | 
         @@ -13,7 +13,9 @@ 
     | 
|
| 
       13 
13 
     | 
    
         
             
            # limitations under the License.
         
     | 
| 
       14 
14 
     | 
    
         | 
| 
       15 
15 
     | 
    
         
             
            require 'mongo/cluster/topology'
         
     | 
| 
       16 
     | 
    
         
            -
            require 'mongo/cluster/ 
     | 
| 
      
 16 
     | 
    
         
            +
            require 'mongo/cluster/reapers/socket_reaper'
         
     | 
| 
      
 17 
     | 
    
         
            +
            require 'mongo/cluster/reapers/cursor_reaper'
         
     | 
| 
      
 18 
     | 
    
         
            +
            require 'mongo/cluster/periodic_executor'
         
     | 
| 
       17 
19 
     | 
    
         
             
            require 'mongo/cluster/app_metadata'
         
     | 
| 
       18 
20 
     | 
    
         | 
| 
       19 
21 
     | 
    
         
             
            module Mongo
         
     | 
| 
         @@ -189,9 +191,11 @@ module Mongo 
     | 
|
| 
       189 
191 
     | 
    
         
             
                  ) if @servers.size > 1
         
     | 
| 
       190 
192 
     | 
    
         | 
| 
       191 
193 
     | 
    
         
             
                  @cursor_reaper = CursorReaper.new
         
     | 
| 
       192 
     | 
    
         
            -
                  @ 
     | 
| 
      
 194 
     | 
    
         
            +
                  @socket_reaper = SocketReaper.new(self)
         
     | 
| 
      
 195 
     | 
    
         
            +
                  @periodic_executor = PeriodicExecutor.new(@cursor_reaper, @socket_reaper)
         
     | 
| 
      
 196 
     | 
    
         
            +
                  @periodic_executor.run!
         
     | 
| 
       193 
197 
     | 
    
         | 
| 
       194 
     | 
    
         
            -
                  ObjectSpace.define_finalizer(self, self.class.finalize(pools, @ 
     | 
| 
      
 198 
     | 
    
         
            +
                  ObjectSpace.define_finalizer(self, self.class.finalize(pools, @periodic_executor))
         
     | 
| 
       195 
199 
     | 
    
         
             
                end
         
     | 
| 
       196 
200 
     | 
    
         | 
| 
       197 
201 
     | 
    
         
             
                # Finalize the cluster for garbage collection. Disconnects all the scoped
         
     | 
| 
         @@ -206,10 +210,9 @@ module Mongo 
     | 
|
| 
       206 
210 
     | 
    
         
             
                # @return [ Proc ] The Finalizer.
         
     | 
| 
       207 
211 
     | 
    
         
             
                #
         
     | 
| 
       208 
212 
     | 
    
         
             
                # @since 2.2.0
         
     | 
| 
       209 
     | 
    
         
            -
                def self.finalize(pools,  
     | 
| 
      
 213 
     | 
    
         
            +
                def self.finalize(pools, periodic_executor)
         
     | 
| 
       210 
214 
     | 
    
         
             
                  proc do
         
     | 
| 
       211 
     | 
    
         
            -
                     
     | 
| 
       212 
     | 
    
         
            -
                    cursor_reaper.stop!
         
     | 
| 
      
 215 
     | 
    
         
            +
                    periodic_executor.stop!
         
     | 
| 
       213 
216 
     | 
    
         
             
                    pools.values.each do |pool|
         
     | 
| 
       214 
217 
     | 
    
         
             
                      pool.disconnect!
         
     | 
| 
       215 
218 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -371,8 +374,7 @@ module Mongo 
     | 
|
| 
       371 
374 
     | 
    
         
             
                #
         
     | 
| 
       372 
375 
     | 
    
         
             
                # @since 2.1.0
         
     | 
| 
       373 
376 
     | 
    
         
             
                def disconnect!
         
     | 
| 
       374 
     | 
    
         
            -
                   
     | 
| 
       375 
     | 
    
         
            -
                  @cursor_reaper.stop!
         
     | 
| 
      
 377 
     | 
    
         
            +
                  @periodic_executor.stop!
         
     | 
| 
       376 
378 
     | 
    
         
             
                  @servers.each { |server| server.disconnect! } and true
         
     | 
| 
       377 
379 
     | 
    
         
             
                end
         
     | 
| 
       378 
380 
     | 
    
         | 
| 
         @@ -387,7 +389,7 @@ module Mongo 
     | 
|
| 
       387 
389 
     | 
    
         
             
                def reconnect!
         
     | 
| 
       388 
390 
     | 
    
         
             
                  scan!
         
     | 
| 
       389 
391 
     | 
    
         
             
                  servers.each { |server| server.reconnect! }
         
     | 
| 
       390 
     | 
    
         
            -
                  @ 
     | 
| 
      
 392 
     | 
    
         
            +
                  @periodic_executor.restart! and true
         
     | 
| 
       391 
393 
     | 
    
         
             
                end
         
     | 
| 
       392 
394 
     | 
    
         | 
| 
       393 
395 
     | 
    
         
             
                # Add hosts in a description to the cluster.
         
     | 
| 
         @@ -474,7 +476,7 @@ module Mongo 
     | 
|
| 
       474 
476 
     | 
    
         
             
                # @example Update the cluster time.
         
     | 
| 
       475 
477 
     | 
    
         
             
                #   cluster.update_cluster_time(result)
         
     | 
| 
       476 
478 
     | 
    
         
             
                #
         
     | 
| 
       477 
     | 
    
         
            -
                # @param [ Operation::Result ] The operation result containing the cluster time.
         
     | 
| 
      
 479 
     | 
    
         
            +
                # @param [ Operation::Result ] result The operation result containing the cluster time.
         
     | 
| 
       478 
480 
     | 
    
         
             
                #
         
     | 
| 
       479 
481 
     | 
    
         
             
                # @return [ Object ] The cluster time.
         
     | 
| 
       480 
482 
     | 
    
         
             
                #
         
     | 
| 
         @@ -484,8 +486,8 @@ module Mongo 
     | 
|
| 
       484 
486 
     | 
    
         
             
                    @cluster_time_lock.synchronize do
         
     | 
| 
       485 
487 
     | 
    
         
             
                      if @cluster_time.nil?
         
     | 
| 
       486 
488 
     | 
    
         
             
                        @cluster_time = cluster_time_doc
         
     | 
| 
       487 
     | 
    
         
            -
                       
     | 
| 
       488 
     | 
    
         
            -
                        @cluster_time = cluster_time_doc 
     | 
| 
      
 489 
     | 
    
         
            +
                      elsif cluster_time_doc[CLUSTER_TIME] > @cluster_time[CLUSTER_TIME]
         
     | 
| 
      
 490 
     | 
    
         
            +
                        @cluster_time = cluster_time_doc
         
     | 
| 
       489 
491 
     | 
    
         
             
                      end
         
     | 
| 
       490 
492 
     | 
    
         
             
                    end
         
     | 
| 
       491 
493 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -0,0 +1,106 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # Copyright (C) 2014-2017 MongoDB, Inc.
         
     | 
| 
      
 2 
     | 
    
         
            +
            #
         
     | 
| 
      
 3 
     | 
    
         
            +
            # Licensed under the Apache License, Version 2.0 (the "License");
         
     | 
| 
      
 4 
     | 
    
         
            +
            # you may not use this file except in compliance with the License.
         
     | 
| 
      
 5 
     | 
    
         
            +
            # You may obtain a copy of the License at
         
     | 
| 
      
 6 
     | 
    
         
            +
            #
         
     | 
| 
      
 7 
     | 
    
         
            +
            #   http://www.apache.org/licenses/LICENSE-2.0
         
     | 
| 
      
 8 
     | 
    
         
            +
            #
         
     | 
| 
      
 9 
     | 
    
         
            +
            # Unless required by applicable law or agreed to in writing, software
         
     | 
| 
      
 10 
     | 
    
         
            +
            # distributed under the License is distributed on an "AS IS" BASIS,
         
     | 
| 
      
 11 
     | 
    
         
            +
            # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
         
     | 
| 
      
 12 
     | 
    
         
            +
            # See the License for the specific language governing permissions and
         
     | 
| 
      
 13 
     | 
    
         
            +
            # limitations under the License.
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
            module Mongo
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
              class Cluster
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                # A manager that calls #execute on its executors at a regular interval.
         
     | 
| 
      
 20 
     | 
    
         
            +
                #
         
     | 
| 
      
 21 
     | 
    
         
            +
                # @api private
         
     | 
| 
      
 22 
     | 
    
         
            +
                #
         
     | 
| 
      
 23 
     | 
    
         
            +
                # @since 2.5.0
         
     | 
| 
      
 24 
     | 
    
         
            +
                class PeriodicExecutor
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                  # The default time interval for the periodic executor to execute.
         
     | 
| 
      
 27 
     | 
    
         
            +
                  #
         
     | 
| 
      
 28 
     | 
    
         
            +
                  # @since 2.5.0
         
     | 
| 
      
 29 
     | 
    
         
            +
                  FREQUENCY = 5
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                  # Create a periodic executor.
         
     | 
| 
      
 32 
     | 
    
         
            +
                  #
         
     | 
| 
      
 33 
     | 
    
         
            +
                  # @example Create a PeriodicExecutor.
         
     | 
| 
      
 34 
     | 
    
         
            +
                  #   Mongo::Cluster::PeriodicExecutor.new(reaper, reaper2)
         
     | 
| 
      
 35 
     | 
    
         
            +
                  #
         
     | 
| 
      
 36 
     | 
    
         
            +
                  # @api private
         
     | 
| 
      
 37 
     | 
    
         
            +
                  #
         
     | 
| 
      
 38 
     | 
    
         
            +
                  # @since 2.5.0
         
     | 
| 
      
 39 
     | 
    
         
            +
                  def initialize(*executors)
         
     | 
| 
      
 40 
     | 
    
         
            +
                    @thread = nil
         
     | 
| 
      
 41 
     | 
    
         
            +
                    @executors = executors
         
     | 
| 
      
 42 
     | 
    
         
            +
                  end
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                  # Start the thread.
         
     | 
| 
      
 45 
     | 
    
         
            +
                  #
         
     | 
| 
      
 46 
     | 
    
         
            +
                  # @example Start the periodic executor's thread.
         
     | 
| 
      
 47 
     | 
    
         
            +
                  #   periodic_executor.run!
         
     | 
| 
      
 48 
     | 
    
         
            +
                  #
         
     | 
| 
      
 49 
     | 
    
         
            +
                  # @api private
         
     | 
| 
      
 50 
     | 
    
         
            +
                  #
         
     | 
| 
      
 51 
     | 
    
         
            +
                  # @since 2.5.0
         
     | 
| 
      
 52 
     | 
    
         
            +
                  def run!
         
     | 
| 
      
 53 
     | 
    
         
            +
                    @thread && @thread.alive? ? @thread : start!
         
     | 
| 
      
 54 
     | 
    
         
            +
                  end
         
     | 
| 
      
 55 
     | 
    
         
            +
                  alias :restart! :run!
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
                  # Stop the executor's thread.
         
     | 
| 
      
 58 
     | 
    
         
            +
                  #
         
     | 
| 
      
 59 
     | 
    
         
            +
                  # @example Stop the executors's thread.
         
     | 
| 
      
 60 
     | 
    
         
            +
                  #   periodic_executor.stop!
         
     | 
| 
      
 61 
     | 
    
         
            +
                  #
         
     | 
| 
      
 62 
     | 
    
         
            +
                  # @api private
         
     | 
| 
      
 63 
     | 
    
         
            +
                  #
         
     | 
| 
      
 64 
     | 
    
         
            +
                  # @since 2.5.0
         
     | 
| 
      
 65 
     | 
    
         
            +
                  def stop!
         
     | 
| 
      
 66 
     | 
    
         
            +
                    begin; flush; rescue; end
         
     | 
| 
      
 67 
     | 
    
         
            +
                    @thread.kill && @thread.stop?
         
     | 
| 
      
 68 
     | 
    
         
            +
                  end
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
                  # Trigger an execute call on each reaper.
         
     | 
| 
      
 71 
     | 
    
         
            +
                  #
         
     | 
| 
      
 72 
     | 
    
         
            +
                  # @example Trigger all reapers.
         
     | 
| 
      
 73 
     | 
    
         
            +
                  #   periodic_executor.execute
         
     | 
| 
      
 74 
     | 
    
         
            +
                  #
         
     | 
| 
      
 75 
     | 
    
         
            +
                  # @api private
         
     | 
| 
      
 76 
     | 
    
         
            +
                  #
         
     | 
| 
      
 77 
     | 
    
         
            +
                  # @since 2.5.0
         
     | 
| 
      
 78 
     | 
    
         
            +
                  def execute
         
     | 
| 
      
 79 
     | 
    
         
            +
                    @executors.each(&:execute) and true
         
     | 
| 
      
 80 
     | 
    
         
            +
                  end
         
     | 
| 
      
 81 
     | 
    
         
            +
             
     | 
| 
      
 82 
     | 
    
         
            +
                  # Execute all pending operations.
         
     | 
| 
      
 83 
     | 
    
         
            +
                  #
         
     | 
| 
      
 84 
     | 
    
         
            +
                  # @example Execute all pending operations.
         
     | 
| 
      
 85 
     | 
    
         
            +
                  #   periodic_executor.flush
         
     | 
| 
      
 86 
     | 
    
         
            +
                  #
         
     | 
| 
      
 87 
     | 
    
         
            +
                  # @api private
         
     | 
| 
      
 88 
     | 
    
         
            +
                  #
         
     | 
| 
      
 89 
     | 
    
         
            +
                  # @since 2.5.0
         
     | 
| 
      
 90 
     | 
    
         
            +
                  def flush
         
     | 
| 
      
 91 
     | 
    
         
            +
                    @executors.each(&:flush) and true
         
     | 
| 
      
 92 
     | 
    
         
            +
                  end
         
     | 
| 
      
 93 
     | 
    
         
            +
             
     | 
| 
      
 94 
     | 
    
         
            +
                  private
         
     | 
| 
      
 95 
     | 
    
         
            +
             
     | 
| 
      
 96 
     | 
    
         
            +
                  def start!
         
     | 
| 
      
 97 
     | 
    
         
            +
                    @thread = Thread.new(FREQUENCY) do |i|
         
     | 
| 
      
 98 
     | 
    
         
            +
                      loop do
         
     | 
| 
      
 99 
     | 
    
         
            +
                        sleep(i)
         
     | 
| 
      
 100 
     | 
    
         
            +
                        execute
         
     | 
| 
      
 101 
     | 
    
         
            +
                      end
         
     | 
| 
      
 102 
     | 
    
         
            +
                    end
         
     | 
| 
      
 103 
     | 
    
         
            +
                  end
         
     | 
| 
      
 104 
     | 
    
         
            +
                end
         
     | 
| 
      
 105 
     | 
    
         
            +
              end
         
     | 
| 
      
 106 
     | 
    
         
            +
            end
         
     |