-
Notifications
You must be signed in to change notification settings - Fork 1.1k
PYTHON-436 Add support for a maximum number of open connections #163
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
… pool. Passes most tests but causes 19 errors and 7 failures.
…ing it is an error
…t tests pass I'll fix the tests to work with a Queue instead of a set
…stead of a set, now all current tests pass without the hacks
…erted it. All tests still passing
Hi Justin, Thanks for working on this. I've milestoned the related ticket for PyMongo 2.6 (2.5 will ship this week). Would you be willing to do more work on this for that release? |
I'd be happy to finish this off, but I'd like some guidance on what else is needed for the pull request to be accepted. I'm looking into the additional parameters that PYTHON-436 references but this pull request is complete in that max_open_sockets works as max_pool_size is expected to. |
Here is a list of things we think should change to finish this off:
Thanks again for working on this. We really appreciate it. If this is more work than you have time to handle we're happy to merge what you've already sent and make the modifications. You'll get credit in git history for this commit. Let us know. |
Thanks for the feedback! |
Conflicts: doc/contributors.rst
for max_size to 100. Some tests now fail and need to be carefully cleaned up or code fixed.
Let's do a local copy in thread_util.py so we don't have to worry about implementation differences in the various different interpreters / versions PyMongo supports.
Definitely need to make sure force is only used by the replica set monitor. It's the only valid use case.
Sure, my email address is in the readme. May be better to explain it all through email. The short version is connectTimeoutMS is meant to keep your application from hanging forever if the host is responding very slowly or not at all (DNS failure, network partition, flaky firewall dropping packets, the machine / vm is down, etc.) and is passed to socket.settimeout. waitQueueTimeoutMS is used with waitQueueMultiple to specify how long a thread is allowed to wait on a semaphore for a socket to be available before an exception is raised. For example, let's say you have a maxPoolSize of 10 and a waitQueueMultiple of 5. In that case the first 10 threads would immediately get a socket, the next 40 would be able to wait on a semaphore for waitQueueTimeoutMS millis before an exception is raised. Any thread beyond the first 50 would immediately get an exception.
I haven't done a thorough review yet but I don't think so. Thanks again for working on this. =) |
before opening a new connection.
* Copy Condition as well to allow Semaphore to support greenlet/gevent pools without patching thread. * Patch Condition with Python 2.x timeout support. * Rename NoopSemaphore to DummySemaphore (gevent has one named this) * Add greenlet/gevent support to Semaphore, BoundedSemaphore, Condition, and SynchronizedCounter.
required by it in favor of marking sock_info as forced and letting that help us keep the semaphore clean.
emulate threading.Lock exactly.
Python 2.6 and on_thread_died not being called
with Python 2.6, but don't fail the test for Python < 2.7 for now
At this point I think that the pull request is about as good as it's going to get. There is still a request socket leak issue which appears to be a race condition in Python 2.6 when the time between accessing threadlocals and thread death is too small, leading me to think that the issue occurs when there is no context switch between these two events (or possibly just when no other thread accesses the threadlocal between these events). I still believe that this is an existing failure case with pymongo and Python 2.6 and is not related to the changes in this pull request, so merging this pull request should not introduce any more potential failure cases with regards to socket leakage. |
Justin, I think we're ready to merge this. Could you please undo the "install" line in .travis.yml, and remove the "import atexit" statement from pool.py? Then squash this whole series of commits so we can bring it in as a single commit. Thanks! |
Great, I'll do the squash in another branch and open a new pull request then. As for the .travis.yml change, I needed that in order to get Travis CI working for me. Do you not want this merged because it is irrelevant to this patch or will it break your internal CI? ;-) |
Oh, weird; if the Travis change is useful go ahead and include it. We don't On Mon, Apr 15, 2013 at 4:23 PM, Justin Patrin [email protected]:
|
@@ -273,6 +281,9 @@ def __init__(self, host=None, port=None, max_pool_size=10, | |||
|
|||
self.__net_timeout = options.get('sockettimeoutms') | |||
self.__conn_timeout = options.get('connecttimeoutms') | |||
self.__wait_queue_timeout = options.get('waitqueuetimeoutms') | |||
self.__wait_queue_multiple = options.get('waitqueuemultiple') |
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.
You need to add these waitqueue* options to pymongo.common.VALIDATORS. waitqueutimeoutms can use validate_timeout_or_none and waitqueuemultiple can use validate_positive_integer_or_none. You should also add tests for this. As it is now neither of these options can be passed as keyword params or in a URI. Using either of them raises ConfigurationError.
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.
Done. Thanks.
Yeah, Travis was failing due to bad permissions on shared memory, so the On Mon, Apr 15, 2013 at 1:43 PM, A. Jesse Jiryu Davis <
Justin Patrin |
…ctions rather than just the idle connections in the pool. Also add support for waitQueueTimeoutMS and waitQueueMultiple.
Closing this pull request, will open a new one with the squashed PYTHON-436 branch. |
This patch adds a semaphore to keep track of sockets opened and released from the pool in order to be able to enforce a maximum number of open connections. I've also fixed a few places where sockets were being leaked from the pool (never returned) and an extra socket return in a test.
Timeout support for the semaphore is added in this patch to support connection timeouts properly.
Changes have been made to make sure that internal functions can always get a socket from the pool. even if it's at max, so it's possible for more than the configured max to be opened, but these "forced" connections are still tracked and should always be returned.
https://jira.mongodb.org/browse/PYTHON-436