Uploaded image for project: 'Ruby Driver'
  1. Ruby Driver
  2. RUBY-3025

getMore with a batchSize of 0 being sent if a limit of 0 is set

    • Type: Icon: Bug Bug
    • Resolution: Fixed
    • Priority: Icon: Major - P3 Major - P3
    • 2.18.1, 2.17.3
    • Affects Version/s: None
    • Component/s: None
    • None

      At some point between 2.6 and 2.17, the Ruby driver began associating an operation's limit as the batchSize for a getMore command. For example:

      require 'bundler/inline'
      
      gemfile do
        source 'https://rubygems.org'
        gem 'mongo', '2.6.2'
        # uncomment below and comment out above to use 2.17.1 instead
        #gem 'mongo', '2.17.1'
      end
      
      client = Mongo::Client.new('mongodb://localhost:27017/test')
      collection = client[:foo]
      collection.drop
      collection.insert_many([].fill({ "bar": "baz" }, 0, 102))
      
      Mongo::Logger.logger.level = Logger::DEBUG
      collection.find({bar: "baz"}, { limit: 0 }).to_a.size rescue nil
      

      When the above is run using 2.6.2 the output from command monitor will be:

      D, [2022-06-13T15:55:27.733672 #45047] DEBUG -- : MONGODB | localhost:27017 | test.getMore | STARTED | {"getMore"=>5932819205641482470, "collection"=>"foo", "lsid"=>{"id"=><BSON::Binary:0x1320 type=uuid data=0x1fe355952b144c09...>}}
      D, [2022-06-13T15:55:27.734129 #45047] DEBUG -- : MONGODB | localhost:27017 | test.getMore | SUCCEEDED | 0.000s
      

      Running the same code wiht the 2.17.1 driver will fail, showing the batchSize having been set to 0:

      D, [2022-06-13T15:54:51.772890 #44733] DEBUG -- : MONGODB | localhost:27017 req:8 conn:1:1 sconn:11 | test.getMore | STARTED | {"getMore"=>#<BSON::Int64:0x00007f87b6159d80 @value=7618985499189845324>, "collection"=>"foo", "batchSize"=>0, "$db"=>"test", "lsid"=>{"id"=><BSON::Binary:0x1420 type=uuid data=0xa8480abeaa674f4a...>}}
      D, [2022-06-13T15:54:51.773331 #44733] DEBUG -- : MONGODB | localhost:27017 req:8 | test.getMore | FAILED | [2:BadValue]: Batch size for getMore must be positive, but received: 0 | 0.00031999999191612005s
      

      Further instrumenting the code to use TracePoints shows the builder implementations changed significantly between these versions:

      require 'bundler/inline'
      
      gemfile do
        source 'https://rubygems.org'
        gem 'mongo', '2.6.2'
        #gem 'mongo', '2.17.1'
      end
      
      client = Mongo::Client.new('mongodb://localhost:27017/test')
      collection = client[:foo]
      collection.drop
      collection.insert_many([].fill({ "bar": "baz" }, 0, 102))
      
      def with_tracepoint
        trace = []
        tp = TracePoint.new(:call) do |x|
          trace << "#{x.defined_class}##{x.method_id.to_s} @ #{x.path}"
        end
        tp.enable
        yield
        return trace
      ensure
        tp.disable unless tp.nil?
      end
      
      Mongo::Logger.logger.level = Logger::INFO
      puts with_tracepoint { collection.find({bar: "baz"}, { limit: 0 }).to_a.size rescue nil }
      

      The getMore initialization changes from Mongo::Cursor::Builder::GetMoreCommand#initialize to Mongo::Operation::GetMore::CommandBuilder#selector, and the logic for converting limit and batch size moves from Mongo::Collection::View::Builder::FindCommand#convert_limit_and_batch_size to #<Class:Mongo::Operation::Find::Builder::Command>#convert_limit_and_batch_size!

      Was there a regression in the getMore builder as a result of an overhaul to the builders at some point?

            Assignee:
            dmitry.rybakov@mongodb.com Dmitry Rybakov
            Reporter:
            alex.bevilacqua@mongodb.com Alex Bevilacqua
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: