@@ -177,12 +177,13 @@ def ping(cls, address, *, timeout=None, **config):
177177 return protocol_version
178178
179179 @classmethod
180- def open (cls , address , * , auth = None , timeout = None , ** pool_config ):
180+ def open (cls , address , * , auth = None , timeout = None , routing_context = None , ** pool_config ):
181181 """ Open a new Bolt connection to a given server address.
182182
183183 :param address:
184184 :param auth:
185- :param timeout: The connection timeout
185+ :param timeout: the connection timeout in seconds
186+ :param routing_context: dict containing routing context
186187 :param pool_config:
187188 :return:
188189 :raise BoltHandshakeError: raised if the Bolt Protocol can not negotiate a protocol version.
@@ -200,15 +201,15 @@ def open(cls, address, *, auth=None, timeout=None, **pool_config):
200201 if pool_config .protocol_version == (3 , 0 ):
201202 # Carry out Bolt subclass imports locally to avoid circular dependency issues.
202203 from neo4j .io ._bolt3 import Bolt3
203- connection = Bolt3 (address , s , pool_config .max_connection_lifetime , auth = auth , user_agent = pool_config .user_agent )
204+ connection = Bolt3 (address , s , pool_config .max_connection_lifetime , auth = auth , user_agent = pool_config .user_agent , routing_context = routing_context )
204205 elif pool_config .protocol_version == (4 , 0 ):
205206 # Carry out Bolt subclass imports locally to avoid circular dependency issues.
206207 from neo4j .io ._bolt4x0 import Bolt4x0
207- connection = Bolt4x0 (address , s , pool_config .max_connection_lifetime , auth = auth , user_agent = pool_config .user_agent )
208+ connection = Bolt4x0 (address , s , pool_config .max_connection_lifetime , auth = auth , user_agent = pool_config .user_agent , routing_context = routing_context )
208209 elif pool_config .protocol_version == (4 , 1 ):
209210 # Carry out Bolt subclass imports locally to avoid circular dependency issues.
210211 from neo4j .io ._bolt4x1 import Bolt4x1
211- connection = Bolt4x1 (address , s , pool_config .max_connection_lifetime , auth = auth , user_agent = pool_config .user_agent )
212+ connection = Bolt4x1 (address , s , pool_config .max_connection_lifetime , auth = auth , user_agent = pool_config .user_agent , routing_context = routing_context )
212213 else :
213214 log .debug ("[#%04X] S: <CLOSE>" , s .getpeername ()[1 ])
214215 s .shutdown (SHUT_RDWR )
@@ -499,27 +500,35 @@ def close(self):
499500class BoltPool (IOPool ):
500501
501502 @classmethod
502- def open (cls , address , * , auth , pool_config , workspace_config ):
503+ def open (cls , address , * , auth , pool_config , workspace_config , routing_context = None ):
503504 """Create a new BoltPool
504505
505506 :param address:
506507 :param auth:
507508 :param pool_config:
508509 :param workspace_config:
510+ :param routing_context:
509511 :return: BoltPool
510512 """
511513
514+ if routing_context is None :
515+ routing_context = {}
516+ elif "address" in routing_context :
517+ raise ConfigurationError ("The key 'address' is reserved for routing context." )
518+ routing_context ["address" ] = str (address )
519+
512520 def opener (addr , timeout ):
513- return Bolt .open (addr , auth = auth , timeout = timeout , ** pool_config )
521+ return Bolt .open (addr , auth = auth , timeout = timeout , routing_context = routing_context , ** pool_config )
514522
515- pool = cls (opener , pool_config , workspace_config , address )
523+ pool = cls (opener , pool_config , workspace_config , routing_context , address )
516524 seeds = [pool .acquire () for _ in range (pool_config .init_size )]
517525 pool .release (* seeds )
518526 return pool
519527
520- def __init__ (self , opener , pool_config , workspace_config , address ):
528+ def __init__ (self , opener , pool_config , workspace_config , routing_context , address ):
521529 super (BoltPool , self ).__init__ (opener , pool_config , workspace_config )
522530 self .address = address
531+ self .routing_context = routing_context
523532
524533 def __repr__ (self ):
525534 return "<{} address={!r}>" .format (self .__class__ .__name__ , self .address )
@@ -545,10 +554,17 @@ def open(cls, *addresses, auth, pool_config, workspace_config, routing_context=N
545554 :return: Neo4jPool
546555 """
547556
557+ address = addresses [0 ]
558+ if routing_context is None :
559+ routing_context = {}
560+ elif "address" in routing_context :
561+ raise ConfigurationError ("The key 'address' is reserved for routing context." )
562+ routing_context ["address" ] = str (address )
563+
548564 def opener (addr , timeout ):
549- return Bolt .open (addr , auth = auth , timeout = timeout , ** pool_config )
565+ return Bolt .open (addr , auth = auth , timeout = timeout , routing_context = routing_context , ** pool_config )
550566
551- pool = cls (opener , pool_config , workspace_config , routing_context , addresses )
567+ pool = cls (opener , pool_config , workspace_config , routing_context , address )
552568
553569 try :
554570 pool .update_routing_table (database = workspace_config .database )
@@ -558,7 +574,7 @@ def opener(addr, timeout):
558574 else :
559575 return pool
560576
561- def __init__ (self , opener , pool_config , workspace_config , routing_context , addresses ):
577+ def __init__ (self , opener , pool_config , workspace_config , routing_context , address ):
562578 """
563579
564580 :param opener:
@@ -569,15 +585,10 @@ def __init__(self, opener, pool_config, workspace_config, routing_context, addre
569585 """
570586 super (Neo4jPool , self ).__init__ (opener , pool_config , workspace_config )
571587 # Each database have a routing table, the default database is a special case.
572- log .debug ("[#0000] C: <NEO4J POOL> routing addresses %r" , addresses )
573- self .init_address = addresses [ 0 ]
574- self .routing_tables = {workspace_config .database : RoutingTable (database = workspace_config .database , routers = addresses )}
588+ log .debug ("[#0000] C: <NEO4J POOL> routing address %r" , address )
589+ self .address = address
590+ self .routing_tables = {workspace_config .database : RoutingTable (database = workspace_config .database , routers = [ address ] )}
575591 self .routing_context = routing_context
576- if self .routing_context is None :
577- self .routing_context = {}
578- elif "address" in self .routing_context :
579- raise ConfigurationError ("The key 'address' is reserved for routing context." )
580- self .routing_context ["address" ] = str (self .init_address )
581592 self .refresh_lock = Lock ()
582593
583594 def __repr__ (self ):
@@ -621,7 +632,7 @@ def fetch_routing_info(self, *, address, timeout, database):
621632 :param address: router address
622633 :param timeout: seconds
623634 :param database: the data base name to get routing table for
624- :param init_address : the address by which the client initially contacted the server as a hint for inclusion in the returned routing table.
635+ :param address : the address by which the client initially contacted the server as a hint for inclusion in the returned routing table.
625636
626637 :return: list of routing records or
627638 None if no connection could be established
0 commit comments