4242from neo4j .meta import version
4343from neo4j .packstream import Packer , Unpacker
4444from neo4j .util import import_best as _import_best
45+ from time import clock
4546
4647ChunkedInputBuffer = _import_best ("neo4j.bolt._io" , "neo4j.bolt.io" ).ChunkedInputBuffer
4748ChunkedOutputBuffer = _import_best ("neo4j.bolt._io" , "neo4j.bolt.io" ).ChunkedOutputBuffer
4849
4950
51+ INFINITE_CONNECTION_LIFETIME = - 1
52+ DEFAULT_MAX_CONNECTION_LIFETIME = INFINITE_CONNECTION_LIFETIME
5053DEFAULT_CONNECTION_TIMEOUT = 5.0
5154DEFAULT_PORT = 7687
5255DEFAULT_USER_AGENT = "neo4j-python/%s" % version
@@ -178,6 +181,8 @@ def __init__(self, address, sock, error_handler, **config):
178181 self .packer = Packer (self .output_buffer )
179182 self .unpacker = Unpacker ()
180183 self .responses = deque ()
184+ self ._max_connection_lifetime = config .get ("max_connection_lifetime" , DEFAULT_MAX_CONNECTION_LIFETIME )
185+ self ._creation_timestamp = clock ()
181186
182187 # Determine the user agent and ensure it is a Unicode value
183188 user_agent = config .get ("user_agent" , DEFAULT_USER_AGENT )
@@ -201,6 +206,7 @@ def __init__(self, address, sock, error_handler, **config):
201206 # Pick up the server certificate, if any
202207 self .der_encoded_server_certificate = config .get ("der_encoded_server_certificate" )
203208
209+ def Init (self ):
204210 response = InitResponse (self )
205211 self .append (INIT , (self .user_agent , self .auth_dict ), response = response )
206212 self .sync ()
@@ -360,6 +366,9 @@ def _unpack(self):
360366 more = False
361367 return details , summary_signature , summary_metadata
362368
369+ def timedout (self ):
370+ return 0 <= self ._max_connection_lifetime <= clock () - self ._creation_timestamp
371+
363372 def sync (self ):
364373 """ Send and fetch all outstanding messages.
365374
@@ -425,7 +434,7 @@ def acquire_direct(self, address):
425434 except KeyError :
426435 connections = self .connections [address ] = deque ()
427436 for connection in list (connections ):
428- if connection .closed () or connection .defunct ():
437+ if connection .closed () or connection .defunct () or connection . timedout () :
429438 connections .remove (connection )
430439 continue
431440 if not connection .in_use :
@@ -600,8 +609,10 @@ def connect(address, ssl_context=None, error_handler=None, **config):
600609 s .shutdown (SHUT_RDWR )
601610 s .close ()
602611 elif agreed_version == 1 :
603- return Connection (address , s , der_encoded_server_certificate = der_encoded_server_certificate ,
612+ connection = Connection (address , s , der_encoded_server_certificate = der_encoded_server_certificate ,
604613 error_handler = error_handler , ** config )
614+ connection .Init ()
615+ return connection
605616 elif agreed_version == 0x48545450 :
606617 log_error ("S: [CLOSE]" )
607618 s .close ()
0 commit comments