diff --git a/pymongo/common.py b/pymongo/common.py index 8ccdc21b6..d77dd7edd 100644 --- a/pymongo/common.py +++ b/pymongo/common.py @@ -607,7 +607,7 @@ URI_OPTIONS_VALIDATOR_MAP = { 'journal': validate_boolean_or_string, 'localthresholdms': validate_positive_float_or_zero, 'maxidletimems': validate_timeout_or_none, - 'maxpoolsize': validate_positive_integer_or_none, + 'maxpoolsize': validate_non_negative_integer_or_none, 'maxstalenessseconds': validate_max_staleness, 'readconcernlevel': validate_string_or_none, 'readpreference': validate_read_preference_mode, diff --git a/pymongo/mongo_client.py b/pymongo/mongo_client.py index 57f623889..11c51f9bc 100644 --- a/pymongo/mongo_client.py +++ b/pymongo/mongo_client.py @@ -207,7 +207,9 @@ class MongoClient(common.BaseObject): - `maxPoolSize` (optional): The maximum allowable number of concurrent connections to each connected server. Requests to a server will block if there are `maxPoolSize` outstanding - connections to the requested server. Defaults to 100. Cannot be 0. + connections to the requested server. Defaults to 100. Can be + either 0 or None, in which case there is no limit on the number + of concurrent connections. - `minPoolSize` (optional): The minimum required number of concurrent connections that the pool will maintain to each connected server. Default is 0. @@ -1004,7 +1006,8 @@ class MongoClient(common.BaseObject): """The maximum allowable number of concurrent connections to each connected server. Requests to a server will block if there are `maxPoolSize` outstanding connections to the requested server. - Defaults to 100. Cannot be 0. + Defaults to 100. Can be either 0 or None, in which case there is no + limit on the number of concurrent connections. When a server's pool has reached `max_pool_size`, operations for that server block waiting for a socket to be returned to the pool. If diff --git a/pymongo/pool.py b/pymongo/pool.py index e85dbeae3..952874abb 100644 --- a/pymongo/pool.py +++ b/pymongo/pool.py @@ -1132,7 +1132,7 @@ class Pool: self.size_cond = threading.Condition(self.lock) self.requests = 0 self.max_pool_size = self.opts.max_pool_size - if self.max_pool_size is None: + if not self.max_pool_size: self.max_pool_size = float('inf') # The second portion of the wait queue. # Enforces: maxConnecting diff --git a/test/test_client.py b/test/test_client.py index 2187bde9d..288c697b2 100644 --- a/test/test_client.py +++ b/test/test_client.py @@ -161,8 +161,7 @@ class ClientUnitTest(unittest.TestCase): self.assertRaises(ConfigurationError, MongoClient, []) def test_max_pool_size_zero(self): - with self.assertRaises(ValueError): - MongoClient(maxPoolSize=0) + MongoClient(maxPoolSize=0) def test_uri_detection(self): self.assertRaises( diff --git a/test/test_pooling.py b/test/test_pooling.py index ea2ed3224..ce0bed87c 100644 --- a/test/test_pooling.py +++ b/test/test_pooling.py @@ -485,10 +485,14 @@ class TestPoolMaxSize(_TestPoolingBase): joinall(threads) self.assertEqual(nthreads, self.n_passed) self.assertTrue(len(cx_pool.sockets) > 1) + self.assertEqual(cx_pool.max_pool_size, float('inf')) + def test_max_pool_size_zero(self): - with self.assertRaises(ValueError): - rs_or_single_client(maxPoolSize=0) + c = rs_or_single_client(maxPoolSize=0) + self.addCleanup(c.close) + pool = get_pool(c) + self.assertEqual(pool.max_pool_size, float('inf')) def test_max_pool_size_with_connection_failure(self): # The pool acquires its semaphore before attempting to connect; ensure diff --git a/test/uri_options/connection-pool-options.json b/test/uri_options/connection-pool-options.json index df90f11df..aae16190b 100644 --- a/test/uri_options/connection-pool-options.json +++ b/test/uri_options/connection-pool-options.json @@ -31,6 +31,17 @@ "auth": null, "options": {} }, + { + "description": "maxPoolSize=0 does not error", + "uri": "mongodb://example.com/?maxPoolSize=0", + "valid": true, + "warning": false, + "hosts": null, + "auth": null, + "options": { + "maxPoolSize": 0 + } + }, { "description": "minPoolSize=0 does not error", "uri": "mongodb://example.com/?minPoolSize=0",