-
Type: Bug
-
Resolution: Done
-
Priority: Major - P3
-
Affects Version/s: 1.7.0
-
Component/s: None
-
Environment:MongoDB 2.0.6
mongo gem 1.7.0
After a ConnectionFailure exception, the ruby driver tries to reconnect automatically on a "read" operation, but not on a "write" operation.
Let's consider a basic example similar to the one given in the tutorial:
require 'rubygems' require 'mongo' @conn= Mongo::Connection.new @db = @conn['sample-db'] @coll= @db['test'] @coll.insert({'a' => 1}) # => BSON::ObjectId('508696b9457d514235000001') @coll.find.each { |doc| puts doc.inspect } # => #<BSON::OrderedHash: ... # kill the mongod process here @coll.find.each { |doc| puts doc.inspect } # => Mongo::ConnectionFailure: Failed to connect to host localhost and port 27017 # re-lauch the mongod process here @coll.find.each { |doc| puts doc.inspect } # => #<BSON::OrderedHash: ...
As long as the mongod process is down, we will get a ConnectionFailure exception, but after re-lauching of the mongod process, read operations will work again.
This is because the Cursor attempts to refresh the connection here: https://github.com/mongodb/mongo-ruby-driver/blob/1.7.0/lib/mongo/cursor.rb#L127
But if we do the same test with a "write" operation, it will not reconnect automatically:
require 'rubygems' require 'mongo' @conn= Mongo::Connection.new @db = @conn['sample-db'] @coll= @db['test'] @coll.insert({'a' => 1}) # => BSON::ObjectId('508696b9457d514235000001') # kill the mongod process here @coll.insert({'a' => 1}) # => Mongo::ConnectionFailure: Operation failed with the following exception: Broken pipe:Broken pipe # re-lauch the mongod process here @coll.insert({'a' => 1}) # => Mongo::ConnectionFailure: Operation failed with the following exception: Broken pipe:Broken pipe
Even after the mongod process relaunch, we only get ConnectionFailure exceptions.
With the mongo gem version 1.6.2, it used to reconnect on reads AND writes because the "send_message_on_socket" function closed the connection, see:
https://github.com/mongodb/mongo-ruby-driver/blob/1.6.2/lib/mongo/networking.rb#L314
It's not the case anymore, see:
https://github.com/mongodb/mongo-ruby-driver/blob/1.7.0/lib/mongo/networking.rb#L284
Does it work that way by design or is it a bug?
To me, it seems to be a regression (since it worked with version 1.6.2) and it breaks code relying on the mongo gem (e.g. the central logger gem which can be stuck without being able to reconnect, although correctly implementing the retry code described in the driver's documentation).