Skip to content

Commit 11dc883

Browse files
RUBY-3332 Fix tailable cursors (#2793)
* RUBY-3332 Fix tailable cursors * Extract method * Fix code review remarks
1 parent 16b0d29 commit 11dc883

File tree

3 files changed

+55
-2
lines changed

3 files changed

+55
-2
lines changed

Diff for: lib/mongo/collection/view.rb

+1
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ def hash
127127
# return in each response from MongoDB.
128128
# @option options [ Hash ] :collation The collation to use.
129129
# @option options [ String ] :comment Associate a comment with the query.
130+
# @option options [ :tailable, :tailable_await ] :cursor_type The type of cursor to use.
130131
# @option options [ Hash ] :explain Execute an explain with the provided
131132
# explain options (known options are :verbose and :verbosity) rather
132133
# than a find.

Diff for: lib/mongo/collection/view/iterable.rb

+15
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,8 @@ def initial_query_op(session)
186186
collection.client.log_warn("The :oplog_replay option is deprecated and ignored by MongoDB 4.4 and later")
187187
end
188188

189+
maybe_set_tailable_options(spec)
190+
189191
if explained?
190192
spec[:explain] = options[:explain]
191193
Operation::Explain.new(spec)
@@ -201,6 +203,19 @@ def send_initial_query(server, session = nil)
201203
def use_query_cache?
202204
QueryCache.enabled? && !collection.system_collection?
203205
end
206+
207+
# Add tailable cusror options to the command specifiction if needed.
208+
#
209+
# @param [ Hash ] spec The command specification.
210+
def maybe_set_tailable_options(spec)
211+
case cursor_type
212+
when :tailable
213+
spec[:tailable] = true
214+
when :tailable_await
215+
spec[:tailable] = true
216+
spec[:await_data] = true
217+
end
218+
end
204219
end
205220
end
206221
end

Diff for: spec/integration/find_options_spec.rb

+39-2
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,20 @@
1313
[ SpecConfig.instance.addresses.first ]
1414
end
1515

16+
let(:client_options) do
17+
{}
18+
end
19+
20+
let(:collection_options) do
21+
{}
22+
end
23+
1624
let(:client) do
1725
ClientRegistry.instance.new_local_client(
1826
seeds,
19-
SpecConfig.instance.test_options.merge(client_options)
27+
SpecConfig.instance.test_options
28+
.merge(database: SpecConfig.instance.test_db)
29+
.merge(client_options)
2030
).tap do |client|
2131
client.subscribe(Mongo::Monitoring::COMMAND, subscriber)
2232
end
@@ -30,8 +40,11 @@
3040
subscriber.started_events.find { |cmd| cmd.command_name == 'find' }
3141
end
3242

43+
let(:should_create_collection) { true }
44+
3345
before do
34-
ClientRegistry.instance.global_client('authorized')['find_options'].drop
46+
client['find_options'].drop
47+
collection.create if should_create_collection
3548
collection.insert_many([ { a: 1 }, { a: 2 }, { a: 3 } ])
3649
end
3750

@@ -71,6 +84,8 @@
7184
{ 'locale' => 'de_AT' }
7285
end
7386

87+
let(:should_create_collection) { false }
88+
7489
it 'uses the collation defined on the collection' do
7590
collection.find({}, collation: collation).to_a
7691
expect(find_command.command['collation']).to eq(collation)
@@ -187,4 +202,26 @@
187202
end
188203
end
189204
end
205+
206+
describe 'cursor type' do
207+
let(:collection_options) do
208+
{ capped: true, size: 1000 }
209+
end
210+
211+
context 'when cursor type is :tailable' do
212+
it 'sets the cursor type to tailable' do
213+
collection.find({}, cursor_type: :tailable).first
214+
expect(find_command.command['tailable']).to be true
215+
expect(find_command.command['awaitData']).to be_falsey
216+
end
217+
end
218+
219+
context 'when cursor type is :tailable_await' do
220+
it 'sets the cursor type to tailable' do
221+
collection.find({}, cursor_type: :tailable_await).first
222+
expect(find_command.command['tailable']).to be true
223+
expect(find_command.command['awaitData']).to be true
224+
end
225+
end
226+
end
190227
end

0 commit comments

Comments
 (0)