-
Notifications
You must be signed in to change notification settings - Fork 532
Avoid sharing sockets between forked processes #585
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Hi @eugeneius We can't use Monitor because we support ruby 1.8.7 in the 1.x series of the driver. Is there a particular test case you can share that recreates the problem you are trying to solve? That way, we can see how to resolve it without Monitor. Also, we have released an rc of a rewrite of the ruby driver. It's available on RubyGems as 2.0.0.rc. Thanks |
The test suite passes on 1.8.7 - is there a known issue with Monitor which means it can't be used? I replaced the Mutex with a Monitor because with this patch I opened a ticket describing the issue I'm seeing: https://jira.mongodb.org/browse/RUBY-877 It only happens a few dozen times a day in production, and I haven't been able to reproduce it locally. Even if |
lib/mongo/connection/node.rb
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the process is not forked, @socket.pid
will always return nil
, which will cause the socket to be closed and reopened on every request, thus causing a significant negative impact on performace.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The pid
property is assigned when a socket is created:
https://github.com/mongodb/mongo-ruby-driver/blob/1.12.0/lib/mongo/connection/socket/ssl_socket.rb#L28
https://github.com/mongodb/mongo-ruby-driver/blob/1.12.0/lib/mongo/connection/socket/tcp_socket.rb#L27
https://github.com/mongodb/mongo-ruby-driver/blob/1.12.0/lib/mongo/connection/socket/unix_socket.rb#L28
This is the same logic being used already in the connection pool code:
https://github.com/mongodb/mongo-ruby-driver/blob/1.12.0/lib/mongo/connection/pool.rb#L224
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, missed that part, was thinking of IO#pid
in core Ruby. :)
My mistake, I did a quick test with 1.8.7 and you have to require 'monitor' in order to use it, whereas you don't with >= 1.9.3 I'm going to do a bit more testing but this patch seems reasonable. Thanks for opening the ticket and taking the time to investigate. |
Ideally, we would have a test for this scenario. If you can write one, that would be great. Otherwise, I'll add one. |
Hi Eugene Thanks again for your contribution. I've taken a closer look at your PR and have a few changes to propose. They can be found in this branch and are being tested in jenkins here. My suggestions are:
Let me know if you'd like to update the PR yourself so I can accept it or if you want me to merge it, then make these changes on top. Thanks again Emily |
Thanks for the code review @estolfo! I've cherry-picked your changes into this branch. |
Perfect, thanks @eugeneius ! |
oh, @eugeneius actually, can you rebase because I commit today? 561e1a6 |
Support for detecting when a socket was established in a different process and automatically discarding it was added to this driver in 997d9b8, and refined in a393557. Instances of the Node class maintain their own sockets for refreshing replica set data; they need to be protected from reuse in the same way.
560e136
to
a7c82af
Compare
Done! |
Avoid sharing sockets between forked processes
hey @eugeneius ! |
Thanks @estolfo, we're upgrading now :) |
Support for detecting when a socket was established in a different process and automatically discarding it was added to this driver in 997d9b8, and refined in a393557.
Instances of the Node class maintain their own sockets for refreshing replica set data; they need to be protected from reuse in the same way.