Skip to content

Commit 75baf21

Browse files
p-mongop
authored andcommitted
Fix RUBY-1935 database#command attempts to retry for EOFError (#1523)
1 parent 1887917 commit 75baf21

File tree

4 files changed

+50
-2
lines changed

4 files changed

+50
-2
lines changed

lib/mongo/client.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -709,7 +709,7 @@ def list_databases(filter = {}, name_only = false, opts = {})
709709
cmd = { listDatabases: 1 }
710710
cmd[:nameOnly] = !!name_only
711711
cmd[:filter] = filter unless filter.empty?
712-
use(Database::ADMIN).command(cmd, opts).first[Database::DATABASES]
712+
use(Database::ADMIN).database.read_command(cmd, opts).first[Database::DATABASES]
713713
end
714714

715715
# Returns a list of Mongo::Database objects.

lib/mongo/collection.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ def with(new_options)
212212
#
213213
# @since 2.0.0
214214
def capped?
215-
database.command(:collstats => name).documents[0][CAPPED]
215+
database.read_command(:collstats => name).documents[0][CAPPED]
216216
end
217217

218218
# Force the collection to be created in the database.

lib/mongo/database.rb

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,37 @@ def collections
159159
#
160160
# @return [ Hash ] The result of the command execution.
161161
def command(operation, opts = {})
162+
txn_read_pref = if opts[:session] && opts[:session].in_transaction?
163+
opts[:session].txn_read_preference
164+
else
165+
nil
166+
end
167+
txn_read_pref ||= opts[:read] || ServerSelector::PRIMARY
168+
Lint.validate_underscore_read_preference(txn_read_pref)
169+
selector = ServerSelector.get(txn_read_pref)
170+
171+
client.send(:with_session, opts) do |session|
172+
server = selector.select_server(cluster, nil, session)
173+
Operation::Command.new({
174+
:selector => operation.dup,
175+
:db_name => name,
176+
:read => selector,
177+
:session => session
178+
}).execute(server)
179+
end
180+
end
181+
182+
# Execute a read command on the database, retrying the read if necessary.
183+
#
184+
# @param [ Hash ] operation The command to execute.
185+
# @param [ Hash ] opts The command options.
186+
#
187+
# @option opts :read [ Hash ] The read preference for this command.
188+
# @option opts :session [ Session ] The session to use for this command.
189+
#
190+
# @return [ Hash ] The result of the command execution.
191+
# @api private
192+
def read_command(operation, opts = {})
162193
txn_read_pref = if opts[:session] && opts[:session].in_transaction?
163194
opts[:session].txn_read_preference
164195
else

spec/integration/retryable_writes_spec.rb

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -737,4 +737,21 @@
737737

738738
it_behaves_like 'an operation that does not support retryable writes'
739739
end
740+
741+
context 'when the operation is database#command' do
742+
743+
let(:operation) do
744+
collection.database.command(ping: 1)
745+
end
746+
747+
let(:expectation) do
748+
0
749+
end
750+
751+
let(:unsuccessful_retry_value) do
752+
0
753+
end
754+
755+
it_behaves_like 'an operation that does not support retryable writes'
756+
end
740757
end

0 commit comments

Comments
 (0)