Skip to content

Commit 2ac4f4f

Browse files
committed
Docstrings
1 parent 6fdb4e1 commit 2ac4f4f

File tree

3 files changed

+82
-67
lines changed

3 files changed

+82
-67
lines changed

neo4j/v1/bolt.py

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -361,24 +361,23 @@ def close(self):
361361

362362

363363
class ConnectionPool(object):
364+
""" A collection of connections to one or more server addresses.
365+
"""
364366

365367
def __init__(self, connector):
366368
self.connector = connector
367-
self._connections = {}
368-
self._lock = Lock()
369-
370-
def __enter__(self):
371-
return self
372-
373-
def __exit__(self, exc_type, exc_val, exc_tb):
374-
self.close()
369+
self.connections = {}
370+
self.lock = Lock()
375371

376372
def acquire(self, address):
377-
with self._lock:
373+
""" Acquire a connection to a given address from the pool.
374+
This method is thread safe.
375+
"""
376+
with self.lock:
378377
try:
379-
connections = self._connections[address]
378+
connections = self.connections[address]
380379
except KeyError:
381-
connections = self._connections[address] = deque()
380+
connections = self.connections[address] = deque()
382381
for connection in list(connections):
383382
if connection.closed or connection.defunct:
384383
connections.remove(connection)
@@ -392,18 +391,24 @@ def acquire(self, address):
392391
return connection
393392

394393
def release(self, connection):
395-
with self._lock:
394+
""" Release a connection back into the pool.
395+
This method is thread safe.
396+
"""
397+
with self.lock:
396398
connection.in_use = False
397399

398400
def close(self):
399-
with self._lock:
400-
for _, connections in self._connections.items():
401+
""" Close all connections and empty the pool.
402+
This method is thread safe.
403+
"""
404+
with self.lock:
405+
for _, connections in self.connections.items():
401406
for connection in connections:
402407
try:
403408
connection.close()
404409
except IOError:
405410
pass
406-
self._connections.clear()
411+
self.connections.clear()
407412

408413

409414
class CertificateStore(object):

neo4j/v1/session.py

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,11 @@ def __exit__(self, exc_type, exc_value, traceback):
173173
self.close()
174174

175175
def session(self, access_mode=None):
176+
""" Create a new session using a connection from the driver connection
177+
pool. Session creation is a lightweight operation and sessions are
178+
not thread safe, therefore a session should generally be short-lived
179+
within a single thread.
180+
"""
176181
raise NotImplementedError()
177182

178183
def close(self):
@@ -191,9 +196,6 @@ def __init__(self, address, **config):
191196
Driver.__init__(self, lambda a: connect(a, security_plan.ssl_context, **config))
192197

193198
def session(self, access_mode=None):
194-
""" Create a new session based on the graph database details
195-
specified within this driver:
196-
"""
197199
return Session(self.pool.acquire(self.address))
198200

199201

@@ -205,6 +207,9 @@ def parse_address(address):
205207

206208

207209
class Router(object):
210+
""" The `Router` class contains logic for discovering servers within a
211+
cluster that supports routing.
212+
"""
208213

209214
timer = monotonic
210215

@@ -217,10 +222,15 @@ def __init__(self, pool, *routers):
217222
self.writers = RoundRobinSet()
218223

219224
def stale(self):
225+
""" Indicator for whether routing information is out of date or
226+
incomplete.
227+
"""
220228
expired = self.expiry_time is None or self.expiry_time <= self.timer()
221229
return expired or len(self.routers) <= 1 or not self.readers or not self.writers
222230

223231
def discover(self):
232+
""" Perform cluster member discovery.
233+
"""
224234
with self.lock:
225235
if not self.routers:
226236
raise ServiceUnavailable("No routers available")
@@ -249,11 +259,15 @@ def discover(self):
249259
raise ServiceUnavailable("Unable to establish routing information")
250260

251261
def acquire_read_connection(self):
262+
""" Acquire a connection to a read server.
263+
"""
252264
if self.stale():
253265
self.discover()
254266
return self.pool.acquire(next(self.readers))
255267

256268
def acquire_write_connection(self):
269+
""" Acquire a connection to a write server.
270+
"""
257271
if self.stale():
258272
self.discover()
259273
return self.pool.acquire(next(self.writers))

test/test_connection.py

Lines changed: 45 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
# See the License for the specific language governing permissions and
1919
# limitations under the License.
2020

21+
from socket import create_connection
2122

2223
from neo4j.v1.bolt import ConnectionPool
2324

@@ -40,65 +41,60 @@ def close(self):
4041
self.socket.close()
4142

4243

43-
def connector(address):
44-
from socket import create_connection
45-
return QuickConnection(create_connection(address))
46-
44+
class ConnectionPoolTestCase(ServerTestCase):
4745

48-
def assert_pool_size(pool, address, expected_active, expected_inactive):
49-
try:
50-
connections = pool._connections[address]
51-
except KeyError:
52-
assert 0 == expected_active
53-
assert 0 == expected_inactive
54-
else:
55-
assert len([c for c in connections if c.in_use]) == expected_active
56-
assert len([c for c in connections if not c.in_use]) == expected_inactive
46+
def setUp(self):
47+
self.pool = ConnectionPool(lambda a: QuickConnection(create_connection(a)))
5748

49+
def tearDown(self):
50+
self.pool.close()
5851

59-
class ConnectionPoolTestCase(ServerTestCase):
52+
def assert_pool_size(self, address, expected_active, expected_inactive):
53+
try:
54+
connections = self.pool.connections[address]
55+
except KeyError:
56+
assert 0 == expected_active
57+
assert 0 == expected_inactive
58+
else:
59+
assert len([c for c in connections if c.in_use]) == expected_active
60+
assert len([c for c in connections if not c.in_use]) == expected_inactive
6061

6162
def test_can_acquire(self):
62-
with ConnectionPool(connector) as pool:
63-
address = ("127.0.0.1", 7687)
64-
connection = pool.acquire(address)
65-
assert connection.address == address
66-
assert_pool_size(pool, address, 1, 0)
63+
address = ("127.0.0.1", 7687)
64+
connection = self.pool.acquire(address)
65+
assert connection.address == address
66+
self.assert_pool_size(address, 1, 0)
6767

6868
def test_can_acquire_twice(self):
69-
with ConnectionPool(connector) as pool:
70-
address = ("127.0.0.1", 7687)
71-
connection_1 = pool.acquire(address)
72-
connection_2 = pool.acquire(address)
73-
assert connection_1.address == address
74-
assert connection_2.address == address
75-
assert connection_1 is not connection_2
76-
assert_pool_size(pool, address, 2, 0)
69+
address = ("127.0.0.1", 7687)
70+
connection_1 = self.pool.acquire(address)
71+
connection_2 = self.pool.acquire(address)
72+
assert connection_1.address == address
73+
assert connection_2.address == address
74+
assert connection_1 is not connection_2
75+
self.assert_pool_size(address, 2, 0)
7776

7877
def test_can_acquire_two_addresses(self):
79-
with ConnectionPool(connector) as pool:
80-
address_1 = ("127.0.0.1", 7687)
81-
address_2 = ("127.0.0.1", 7474)
82-
connection_1 = pool.acquire(address_1)
83-
connection_2 = pool.acquire(address_2)
84-
assert connection_1.address == address_1
85-
assert connection_2.address == address_2
86-
assert_pool_size(pool, address_1, 1, 0)
87-
assert_pool_size(pool, address_2, 1, 0)
78+
address_1 = ("127.0.0.1", 7687)
79+
address_2 = ("127.0.0.1", 7474)
80+
connection_1 = self.pool.acquire(address_1)
81+
connection_2 = self.pool.acquire(address_2)
82+
assert connection_1.address == address_1
83+
assert connection_2.address == address_2
84+
self.assert_pool_size(address_1, 1, 0)
85+
self.assert_pool_size(address_2, 1, 0)
8886

8987
def test_can_acquire_and_release(self):
90-
with ConnectionPool(connector) as pool:
91-
address = ("127.0.0.1", 7687)
92-
connection = pool.acquire(address)
93-
assert_pool_size(pool, address, 1, 0)
94-
pool.release(connection)
95-
assert_pool_size(pool, address, 0, 1)
88+
address = ("127.0.0.1", 7687)
89+
connection = self.pool.acquire(address)
90+
self.assert_pool_size(address, 1, 0)
91+
self.pool.release(connection)
92+
self.assert_pool_size(address, 0, 1)
9693

9794
def test_releasing_twice(self):
98-
with ConnectionPool(connector) as pool:
99-
address = ("127.0.0.1", 7687)
100-
connection = pool.acquire(address)
101-
pool.release(connection)
102-
assert_pool_size(pool, address, 0, 1)
103-
pool.release(connection)
104-
assert_pool_size(pool, address, 0, 1)
95+
address = ("127.0.0.1", 7687)
96+
connection = self.pool.acquire(address)
97+
self.pool.release(connection)
98+
self.assert_pool_size(address, 0, 1)
99+
self.pool.release(connection)
100+
self.assert_pool_size(address, 0, 1)

0 commit comments

Comments
 (0)