@@ -77,57 +77,50 @@ def __init__(self) -> None:
7777 self .connections : Dict [int , TcpServerConnection ] = {}
7878 self .pools : Dict [Tuple [str , int ], Set [TcpServerConnection ]] = {}
7979
80- def add (self , addr : Tuple [str , int ]) -> TcpServerConnection :
81- """Creates and add a new connection to the pool."""
82- new_conn = TcpServerConnection (addr [0 ], addr [1 ])
83- new_conn .connect ()
84- self ._add (new_conn )
85- return new_conn
86-
8780 def acquire (self , addr : Tuple [str , int ]) -> Tuple [bool , TcpServerConnection ]:
8881 """Returns a reusable connection from the pool.
8982
9083 If none exists, will create and return a new connection."""
84+ created , conn = False , None
9185 if addr in self .pools :
9286 for old_conn in self .pools [addr ]:
9387 if old_conn .is_reusable ():
94- old_conn . mark_inuse ()
88+ conn = old_conn
9589 logger .debug (
9690 'Reusing connection#{2} for upstream {0}:{1}' .format (
9791 addr [0 ], addr [1 ], id (old_conn ),
9892 ),
9993 )
100- return False , old_conn
101- new_conn = self .add (addr )
102- logger .debug (
103- 'Created new connection#{2} for upstream {0}:{1}' .format (
104- addr [0 ], addr [1 ], id (new_conn ),
105- ),
106- )
107- return True , new_conn
94+ break
95+ if conn is None :
96+ created , conn = True , self .add (addr )
97+ conn .mark_inuse ()
98+ return created , conn
10899
109100 def release (self , conn : TcpServerConnection ) -> None :
110101 """Release a previously acquired connection.
111102
112- If the connection has not been closed,
113- then it will be retained in the pool for reusability .
103+ Releasing a connection will shutdown and close the socket
104+ including internal pool cleanup .
114105 """
115106 assert not conn .is_reusable ()
116- if conn .closed :
117- logger .debug (
118- 'Removing connection#{2} from pool from upstream {0}:{1}' .format (
119- conn .addr [0 ], conn .addr [1 ], id (conn ),
120- ),
121- )
122- self ._remove (conn .connection .fileno ())
123- else :
124- logger .debug (
125- 'Retaining connection#{2} to upstream {0}:{1}' .format (
126- conn .addr [0 ], conn .addr [1 ], id (conn ),
127- ),
128- )
129- # Reset for reusability
130- conn .reset ()
107+ logger .debug (
108+ 'Removing connection#{2} from pool from upstream {0}:{1}' .format (
109+ conn .addr [0 ], conn .addr [1 ], id (conn ),
110+ ),
111+ )
112+ self ._remove (conn .connection .fileno ())
113+
114+ def retain (self , conn : TcpServerConnection ) -> None :
115+ """Retained previously acquired connection in the pool for reusability."""
116+ assert not conn .closed
117+ logger .debug (
118+ 'Retaining connection#{2} to upstream {0}:{1}' .format (
119+ conn .addr [0 ], conn .addr [1 ], id (conn ),
120+ ),
121+ )
122+ # Reset for reusability
123+ conn .reset ()
131124
132125 async def get_events (self ) -> SelectableEvents :
133126 """Returns read event flag for all reusable connections in the pool."""
@@ -152,10 +145,28 @@ async def handle_events(self, readables: Readables, _writables: Writables) -> bo
152145 self ._remove (fileno )
153146 return False
154147
148+ def add (self , addr : Tuple [str , int ]) -> TcpServerConnection :
149+ """Creates, connects and adds a new connection to the pool.
150+
151+ Returns newly created connection.
152+
153+ NOTE: You must not use the returned connection, instead use `acquire`.
154+ """
155+ new_conn = TcpServerConnection (addr [0 ], addr [1 ])
156+ new_conn .connect ()
157+ self ._add (new_conn )
158+ logger .debug (
159+ 'Created new connection#{2} for upstream {0}:{1}' .format (
160+ addr [0 ], addr [1 ], id (new_conn ),
161+ ),
162+ )
163+ return new_conn
164+
155165 def _add (self , conn : TcpServerConnection ) -> None :
156166 """Adds a new connection to internal data structure."""
157167 if conn .addr not in self .pools :
158168 self .pools [conn .addr ] = set ()
169+ conn ._reusable = True
159170 self .pools [conn .addr ].add (conn )
160171 self .connections [conn .connection .fileno ()] = conn
161172
0 commit comments