From d871f296d912be2c2afab062e74e4d0f97a1950a Mon Sep 17 00:00:00 2001 From: Sylvain Bernier Date: Fri, 8 Jul 2022 19:56:49 -0400 Subject: [PATCH 1/6] Mongo::Collection::View#no_cursor_timeout regression --- spec/mongo/collection/view/readable_spec.rb | 36 +++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/spec/mongo/collection/view/readable_spec.rb b/spec/mongo/collection/view/readable_spec.rb index b99203b2f1..48ba5d30f3 100644 --- a/spec/mongo/collection/view/readable_spec.rb +++ b/spec/mongo/collection/view/readable_spec.rb @@ -1790,6 +1790,42 @@ it 'returns a new View' do expect(new_view).not_to be(view) end + + # The number of open cursors with the option set to prevent timeout. + def current_no_timeout_count + new_view + .client + .command(serverStatus: 1) + .documents + .first + .fetch('metrics') + .fetch('cursor') + .fetch('open') + .fetch('noTimeout') + end + + it 'works' do + # Initialize collection with two documents. + new_view.collection.insert_many([{}, {}]) + + expect(new_view.count).to be == 2 + + # Initial "noTimeout" count should be zero. + states = [current_no_timeout_count] + + # The "noTimeout" count should be one while iterating. + new_view.batch_size(1).each { states << current_no_timeout_count } + + # Final "noTimeout" count should be back to zero. + states << current_no_timeout_count + + # This succeeds on: + # commit aab776ebdfb15ddb9765039f7300e15796de0c5c + # + # This starts failing with [0, 0, 0, 0] from: + # commit 2d9f0217ec904a1952a1ada2136502eefbca562e + expect(states).to be == [0, 1, 1, 0] + end end describe '#projection' do From 858be9e86a24da6cbee21c827b6e17e42335d61d Mon Sep 17 00:00:00 2001 From: Oleg Pudeyev Date: Fri, 15 Jul 2022 15:43:41 -0400 Subject: [PATCH 2/6] adjust description --- spec/mongo/collection/view/readable_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/mongo/collection/view/readable_spec.rb b/spec/mongo/collection/view/readable_spec.rb index 48ba5d30f3..f91071e11c 100644 --- a/spec/mongo/collection/view/readable_spec.rb +++ b/spec/mongo/collection/view/readable_spec.rb @@ -1804,7 +1804,7 @@ def current_no_timeout_count .fetch('noTimeout') end - it 'works' do + it 'is applied on the server' do # Initialize collection with two documents. new_view.collection.insert_many([{}, {}]) From 4ac8089fcf547f8261af70463f0326aecd5c8313 Mon Sep 17 00:00:00 2001 From: Oleg Pudeyev Date: Fri, 15 Jul 2022 15:53:25 -0400 Subject: [PATCH 3/6] add a unit test --- spec/mongo/collection/view/readable_spec.rb | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/spec/mongo/collection/view/readable_spec.rb b/spec/mongo/collection/view/readable_spec.rb index f91071e11c..599cfc5020 100644 --- a/spec/mongo/collection/view/readable_spec.rb +++ b/spec/mongo/collection/view/readable_spec.rb @@ -1791,6 +1791,23 @@ expect(new_view).not_to be(view) end + context 'when sending to server' do + let(:subscriber) { Mrss::EventSubscriber.new } + + before do + authorized_collection.client.subscribe(Mongo::Monitoring::COMMAND, subscriber) + end + + let(:event) do + subscriber.single_command_started_event('find') + end + + it 'is sent to server' do + new_view.to_a + event.command.slice('noCursorTimeout').should == {'noCursorTimeout' => true} + end + end + # The number of open cursors with the option set to prevent timeout. def current_no_timeout_count new_view From 6fa80f2435657207059c2da8b1230f933ddcdac2 Mon Sep 17 00:00:00 2001 From: Oleg Pudeyev Date: Fri, 15 Jul 2022 15:53:35 -0400 Subject: [PATCH 4/6] pass no cursor timeout option to server --- lib/mongo/collection/view/iterable.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/mongo/collection/view/iterable.rb b/lib/mongo/collection/view/iterable.rb index 38a85fe906..943755aed5 100644 --- a/lib/mongo/collection/view/iterable.rb +++ b/lib/mongo/collection/view/iterable.rb @@ -170,6 +170,7 @@ def initial_query_op(session) max_time_ms: options[:max_time_ms], max_value: options[:max_value], min_value: options[:min_value], + no_cursor_timeout: options[:no_cursor_timeout], return_key: options[:return_key], show_disk_loc: options[:show_disk_loc], comment: options[:comment], From 758a1b18c34595fabbc7edb2e8c0d42b69f3d213 Mon Sep 17 00:00:00 2001 From: Oleg Pudeyev Date: Fri, 15 Jul 2022 17:28:35 -0400 Subject: [PATCH 5/6] fix test with auth --- spec/mongo/collection/view/readable_spec.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/spec/mongo/collection/view/readable_spec.rb b/spec/mongo/collection/view/readable_spec.rb index 599cfc5020..c8b66380d4 100644 --- a/spec/mongo/collection/view/readable_spec.rb +++ b/spec/mongo/collection/view/readable_spec.rb @@ -1810,8 +1810,7 @@ # The number of open cursors with the option set to prevent timeout. def current_no_timeout_count - new_view - .client + root_authorized_client .command(serverStatus: 1) .documents .first From 78ec2c2e9b080eda27f3d2d3dfdf331383bd60bb Mon Sep 17 00:00:00 2001 From: Oleg Pudeyev Date: Fri, 15 Jul 2022 17:55:06 -0400 Subject: [PATCH 6/6] restrict to standalones --- spec/mongo/collection/view/readable_spec.rb | 70 +++++++++++---------- 1 file changed, 37 insertions(+), 33 deletions(-) diff --git a/spec/mongo/collection/view/readable_spec.rb b/spec/mongo/collection/view/readable_spec.rb index c8b66380d4..cf5b2385b7 100644 --- a/spec/mongo/collection/view/readable_spec.rb +++ b/spec/mongo/collection/view/readable_spec.rb @@ -1808,39 +1808,43 @@ end end - # The number of open cursors with the option set to prevent timeout. - def current_no_timeout_count - root_authorized_client - .command(serverStatus: 1) - .documents - .first - .fetch('metrics') - .fetch('cursor') - .fetch('open') - .fetch('noTimeout') - end - - it 'is applied on the server' do - # Initialize collection with two documents. - new_view.collection.insert_many([{}, {}]) - - expect(new_view.count).to be == 2 - - # Initial "noTimeout" count should be zero. - states = [current_no_timeout_count] - - # The "noTimeout" count should be one while iterating. - new_view.batch_size(1).each { states << current_no_timeout_count } - - # Final "noTimeout" count should be back to zero. - states << current_no_timeout_count - - # This succeeds on: - # commit aab776ebdfb15ddb9765039f7300e15796de0c5c - # - # This starts failing with [0, 0, 0, 0] from: - # commit 2d9f0217ec904a1952a1ada2136502eefbca562e - expect(states).to be == [0, 1, 1, 0] + context 'integration test' do + require_topology :single + + # The number of open cursors with the option set to prevent timeout. + def current_no_timeout_count + root_authorized_client + .command(serverStatus: 1) + .documents + .first + .fetch('metrics') + .fetch('cursor') + .fetch('open') + .fetch('noTimeout') + end + + it 'is applied on the server' do + # Initialize collection with two documents. + new_view.collection.insert_many([{}, {}]) + + expect(new_view.count).to be == 2 + + # Initial "noTimeout" count should be zero. + states = [current_no_timeout_count] + + # The "noTimeout" count should be one while iterating. + new_view.batch_size(1).each { states << current_no_timeout_count } + + # Final "noTimeout" count should be back to zero. + states << current_no_timeout_count + + # This succeeds on: + # commit aab776ebdfb15ddb9765039f7300e15796de0c5c + # + # This starts failing with [0, 0, 0, 0] from: + # commit 2d9f0217ec904a1952a1ada2136502eefbca562e + expect(states).to be == [0, 1, 1, 0] + end end end