Skip to content

Commit cef9369

Browse files
wustzdycaocuilongCaralHsi
authored
update polardb pool timeout (#441)
* fix:parse_node * fix: * fix:conn --------- Co-authored-by: ccl <[email protected]> Co-authored-by: CaralHsi <[email protected]>
1 parent b3b0baa commit cef9369

File tree

2 files changed

+62
-5
lines changed

2 files changed

+62
-5
lines changed

src/memos/graph_dbs/polardb.py

Lines changed: 59 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -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)

src/memos/memories/textual/tree.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ def get_relevant_subgraph(
260260
center_id=core_id, depth=depth, center_status=center_status
261261
)
262262

263-
if not subgraph["core_node"]:
263+
if subgraph is None or not subgraph["core_node"]:
264264
logger.info(f"Skipping node {core_id} (inactive or not found).")
265265
continue
266266

@@ -281,9 +281,9 @@ def get_relevant_subgraph(
281281
{"id": core_id, "score": score, "core_node": core_node, "neighbors": neighbors}
282282
)
283283

284-
top_core = cores[0]
284+
top_core = cores[0] if cores else None
285285
return {
286-
"core_id": top_core["id"],
286+
"core_id": top_core["id"] if top_core else None,
287287
"nodes": list(all_nodes.values()),
288288
"edges": [{"source": f, "target": t, "type": ty} for (f, t, ty) in all_edges],
289289
}

0 commit comments

Comments
 (0)