diff --git a/CHANGELOG.md b/CHANGELOG.md index b374bead7de39262e2b6e20c492817a4311ca6ed..5d88127d91a1cb81e53cd8fa302cb022c1559ba0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,4 @@ # v2.21.3 -* fixed invalidate for CPManager \ No newline at end of file +* fixed invalidate for CPManager +* exported max_number for CPManager \ No newline at end of file diff --git a/satella/__init__.py b/satella/__init__.py index 93e823c85394c66586ced4aeeb5736b7e83200da..439ab2857f635b19f8b58e5c3cf5151f0810ace8 100644 --- a/satella/__init__.py +++ b/satella/__init__.py @@ -1 +1 @@ -__version__ = '2.21.3a2' +__version__ = '2.21.3a3' diff --git a/satella/coding/resources/cp_manager.py b/satella/coding/resources/cp_manager.py index d7b811b756038aae99516fde0e61f0f9f4e1fc91..ab4c48f4f03254182b145cfb84a9220751bb0212 100644 --- a/satella/coding/resources/cp_manager.py +++ b/satella/coding/resources/cp_manager.py @@ -34,6 +34,7 @@ class CPManager(Monitor, Closeable, tp.Generic[T], metaclass=abc.ABCMeta): :param max_number: maximum number of connections :param max_cycle_no: maximum number of get/put connection cycles. + :ivar max_number: maximum amount of connections. Can be changed during runtime .. warning:: May not work under PyPy for reasons having to do with id's semantics. A RuntimeWarning will be issued when not running under CPython. @@ -82,15 +83,12 @@ class CPManager(Monitor, Closeable, tp.Generic[T], metaclass=abc.ABCMeta): if self.connections.qsize() >= self.max_number: conn = self.connections.get(False, 5) break - elif self.connections.qsize() < self.max_number: + else: conn = self.create_connection() break with Monitor.acquire(self): obj_id = id(conn) - try: - self.id_to_times[obj_id] += 1 - except KeyError: - self.id_to_times[obj_id] = 1 + self.id_to_times[obj_id] = self.id_to_times.get(obj_id, 0) + 1 return conn def release_connection(self, connection: T) -> None: @@ -122,8 +120,7 @@ class CPManager(Monitor, Closeable, tp.Generic[T], metaclass=abc.ABCMeta): :param connection: connection to fail """ - obj_id = id(connection) - self.id_to_times[obj_id] = self.max_cycle_no + self.id_to_times[id(connection)] = self.max_cycle_no @abc.abstractmethod def teardown_connection(self, connection: T) -> None: diff --git a/tests/test_coding/test_resources.py b/tests/test_coding/test_resources.py index cde69630b16db7077828bd84fc0488095d613ecd..d819b2c18f66246b36d12a25af789724541cfce4 100644 --- a/tests/test_coding/test_resources.py +++ b/tests/test_coding/test_resources.py @@ -1,8 +1,8 @@ +import time import unittest from concurrent.futures import Future from satella.coding.concurrent import call_in_separate_thread - from satella.coding.resources import CPManager @@ -17,8 +17,11 @@ class TestResources(unittest.TestCase): Connection.total_connections += 1 self.id = Connection.total_connections self.value_error_emitted = False + self.closed = False def do(self): + if self.closed: + raise RuntimeError('Connection closed') if self.value_error_emitted: raise RuntimeError('do called despite raising ValueError earlier') self.i += 1 @@ -26,6 +29,9 @@ class TestResources(unittest.TestCase): self.value_error_emitted = True raise ValueError() + def close(self): + self.closed = True + class InheritCPManager(CPManager): def __init__(self, *args): super().__init__(*args) @@ -36,6 +42,7 @@ class TestResources(unittest.TestCase): def acquire_connection(self): v = super().acquire_connection() + print(f'Acquiring connection {v.id}') if v.id in self.already_acquired: raise RuntimeError('Reacquiring an acquired connection') self.already_acquired.add(v.id) @@ -45,11 +52,12 @@ class TestResources(unittest.TestCase): super().fail_connection(connection) def release_connection(self, connection) -> None: + print(f'Releasing connection {connection.id}') self.already_acquired.remove(connection.id) super().release_connection(connection) def teardown_connection(self, connection) -> None: - ... + connection.close() cp = InheritCPManager(5, 3) @@ -59,6 +67,7 @@ class TestResources(unittest.TestCase): def do_call(): for _ in range(10): conn = cp.acquire_connection() + time.sleep(1) try: conn.do() except ValueError: @@ -66,9 +75,12 @@ class TestResources(unittest.TestCase): cp.release_connection(conn) - ret = do_call() # type: Future + ret = do_call() # type: Future + ret2 = do_call() + cp.release_connection(conns.pop()) cp.release_connection(conns.pop()) - ret.result(timeout=15) + ret.result(timeout=20) + ret2.result(timeout=20) while conns: cp.release_connection(conns.pop()) diff --git a/tests/test_db.py b/tests/test_db.py index 4a7c336b808971058a3e05a1d8f077898a78dfb4..d3f13cd6522a1bd91e3b9f58e61ef3f032d2e718 100644 --- a/tests/test_db.py +++ b/tests/test_db.py @@ -13,7 +13,6 @@ class RealConnection: def cursor(self): self.cursor_called += 1 - self.commit_called += 1 return Mock() def rollback(self): diff --git a/tests/test_time.py b/tests/test_time.py index 258305adcb6b76df595c757f6e4e7111f646a877..7088544c6bc9f3028e2238446522099010669e02 100644 --- a/tests/test_time.py +++ b/tests/test_time.py @@ -20,7 +20,7 @@ class TestTime(unittest.TestCase): def dupa(a): raise ValueError() - self.assertRaises(dupa, NotImplementedError) + self.assertRaises(NotImplementedError, dupa) def test_measure_as_method(self): self2 = self