@@ -151,6 +151,10 @@ def __init__(self, config: PolarDBGraphDBConfig):
151151 user = user ,
152152 password = password ,
153153 dbname = self .db_name ,
154+ connect_timeout = 60 , # Connection timeout in seconds
155+ keepalives_idle = 40 , # Seconds of inactivity before sending keepalive (should be < server idle timeout)
156+ keepalives_interval = 15 , # Seconds between keepalive retries
157+ keepalives_count = 5 , # Number of keepalive retries before considering connection dead
154158 )
155159
156160 # Keep a reference to the pool for cleanup
@@ -179,7 +183,7 @@ def _get_config_value(self, key: str, default=None):
179183 else :
180184 return getattr (self .config , key , default )
181185
182- def _get_connection (self ):
186+ def _get_connection_old (self ):
183187 """Get a connection from the pool."""
184188 if self ._pool_closed :
185189 raise RuntimeError ("Connection pool has been closed" )
@@ -188,7 +192,60 @@ def _get_connection(self):
188192 conn .autocommit = True
189193 return conn
190194
195+ def _get_connection (self ):
196+ """Get a connection from the pool."""
197+ if self ._pool_closed :
198+ raise RuntimeError ("Connection pool has been closed" )
199+
200+ max_retries = 3
201+ for attempt in range (max_retries ):
202+ try :
203+ conn = self .connection_pool .getconn ()
204+
205+ # Check if connection is closed
206+ if conn .closed != 0 :
207+ # Connection is closed, close it explicitly and try again
208+ try :
209+ conn .close ()
210+ except Exception as e :
211+ logger .warning (f"Failed to close connection: { e } " )
212+ if attempt < max_retries - 1 :
213+ continue
214+ else :
215+ raise RuntimeError ("Pool returned a closed connection" )
216+
217+ # Set autocommit for PolarDB compatibility
218+ conn .autocommit = True
219+ return conn
220+ except Exception as e :
221+ if attempt >= max_retries - 1 :
222+ raise RuntimeError (f"Failed to get a valid connection from pool: { e } " ) from e
223+ continue
224+
191225 def _return_connection (self , connection ):
226+ """Return a connection to the pool."""
227+ if not self ._pool_closed and connection :
228+ try :
229+ # Check if connection is closed
230+ if hasattr (connection , "closed" ) and connection .closed != 0 :
231+ # Connection is closed, just close it and don't return to pool
232+ try :
233+ connection .close ()
234+ except Exception as e :
235+ logger .warning (f"Failed to close connection: { e } " )
236+ return
237+
238+ # Connection is valid, return to pool
239+ self .connection_pool .putconn (connection )
240+ except Exception as e :
241+ # If putconn fails, close the connection
242+ logger .warning (f"Failed to return connection to pool: { e } " )
243+ try :
244+ connection .close ()
245+ except Exception as e :
246+ logger .warning (f"Failed to close connection: { e } " )
247+
248+ def _return_connection_old (self , connection ):
192249 """Return a connection to the pool."""
193250 if not self ._pool_closed and connection :
194251 self .connection_pool .putconn (connection )
@@ -1834,7 +1891,7 @@ def export_graph(
18341891 if include_embedding and embedding_json is not None :
18351892 properties ["embedding" ] = embedding_json
18361893
1837- nodes .append (self ._parse_node (properties ))
1894+ nodes .append (self ._parse_node (json . loads ( properties [ 1 ]) ))
18381895
18391896 except Exception as e :
18401897 logger .error (f"[EXPORT GRAPH - NODES] Exception: { e } " , exc_info = True )
0 commit comments