diff --git a/neo4j/v1/session.py b/neo4j/v1/session.py index 2fda936d8..de96a75bb 100644 --- a/neo4j/v1/session.py +++ b/neo4j/v1/session.py @@ -28,7 +28,7 @@ class which can be used to obtain `Driver` instances that are used for from __future__ import division -from collections import namedtuple +from collections import deque, namedtuple from .compat import integer, perf_counter, string, urlparse from .connection import connect, Response, RUN, PULL_ALL @@ -91,15 +91,19 @@ def __init__(self, url, **config): else: raise ValueError("Unsupported URL scheme: %s" % parsed.scheme) self.config = config + self.sessions = deque() - def session(self, **config): + def session(self): """ Create a new session based on the graph database details specified within this driver: >>> session = driver.session() """ - return Session(connect(self.host, self.port, **dict(self.config, **config))) + try: + return self.sessions.pop() + except IndexError: + return Session(self) class Result(list): @@ -330,11 +334,15 @@ class Session(object): method. """ - def __init__(self, connection): - self.connection = connection + def __init__(self, driver): + self.driver = driver + self.connection = connect(driver.host, driver.port, **driver.config) self.transaction = None self.bench_tests = [] + def __del__(self): + self.connection.close() + def __enter__(self): return self @@ -393,9 +401,9 @@ def run(self, statement, parameters=None): return result def close(self): - """ Shut down and close the session. + """ Return this session to the driver pool it came from. """ - self.connection.close() + self.driver.sessions.appendleft(self) def begin_transaction(self): """ Create a new :class:`.Transaction` within this session. diff --git a/test/test_session.py b/test/test_session.py index 16e2e19b7..92d6aeeb5 100644 --- a/test/test_session.py +++ b/test/test_session.py @@ -30,6 +30,22 @@ def test_must_use_valid_url_scheme(self): with self.assertRaises(ValueError): GraphDatabase.driver("x://xxx") + def test_sessions_are_reused(self): + driver = GraphDatabase.driver("bolt://localhost") + session_1 = driver.session() + session_1.close() + session_2 = driver.session() + session_2.close() + assert session_1 is session_2 + + def test_sessions_are_not_reused_if_still_in_use(self): + driver = GraphDatabase.driver("bolt://localhost") + session_1 = driver.session() + session_2 = driver.session() + session_2.close() + session_1.close() + assert session_1 is not session_2 + def test_can_run_simple_statement(self): session = GraphDatabase.driver("bolt://localhost").session() count = 0