Skip to content

Commit 243726a

Browse files
CopilotMte90
andcommitted
Apply retry logic and timeouts consistently across all database operations
Co-authored-by: Mte90 <403283+Mte90@users.noreply.github.com>
1 parent 810d34d commit 243726a

File tree

1 file changed

+84
-60
lines changed

1 file changed

+84
-60
lines changed

projects.py

Lines changed: 84 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -224,15 +224,19 @@ def get_project(project_path: str) -> Optional[Dict[str, Any]]:
224224
project_path = os.path.abspath(project_path)
225225

226226
registry_path = _get_projects_registry_path()
227-
conn = sqlite3.connect(registry_path)
228-
conn.row_factory = sqlite3.Row
229-
try:
230-
cur = conn.cursor()
231-
cur.execute("SELECT * FROM projects WHERE path = ?", (project_path,))
232-
row = cur.fetchone()
233-
return dict(row) if row else None
234-
finally:
235-
conn.close()
227+
228+
def _get():
229+
conn = sqlite3.connect(registry_path, timeout=10.0)
230+
conn.row_factory = sqlite3.Row
231+
try:
232+
cur = conn.cursor()
233+
cur.execute("SELECT * FROM projects WHERE path = ?", (project_path,))
234+
row = cur.fetchone()
235+
return dict(row) if row else None
236+
finally:
237+
conn.close()
238+
239+
return _retry_on_db_locked(_get)
236240

237241

238242
def get_project_by_id(project_id: str) -> Optional[Dict[str, Any]]:
@@ -248,15 +252,19 @@ def get_project_by_id(project_id: str) -> Optional[Dict[str, Any]]:
248252
_init_registry_db()
249253

250254
registry_path = _get_projects_registry_path()
251-
conn = sqlite3.connect(registry_path)
252-
conn.row_factory = sqlite3.Row
253-
try:
254-
cur = conn.cursor()
255-
cur.execute("SELECT * FROM projects WHERE id = ?", (project_id,))
256-
row = cur.fetchone()
257-
return dict(row) if row else None
258-
finally:
259-
conn.close()
255+
256+
def _get():
257+
conn = sqlite3.connect(registry_path, timeout=10.0)
258+
conn.row_factory = sqlite3.Row
259+
try:
260+
cur = conn.cursor()
261+
cur.execute("SELECT * FROM projects WHERE id = ?", (project_id,))
262+
row = cur.fetchone()
263+
return dict(row) if row else None
264+
finally:
265+
conn.close()
266+
267+
return _retry_on_db_locked(_get)
260268

261269

262270
def list_projects() -> List[Dict[str, Any]]:
@@ -269,15 +277,19 @@ def list_projects() -> List[Dict[str, Any]]:
269277
_init_registry_db()
270278

271279
registry_path = _get_projects_registry_path()
272-
conn = sqlite3.connect(registry_path)
273-
conn.row_factory = sqlite3.Row
274-
try:
275-
cur = conn.cursor()
276-
cur.execute("SELECT * FROM projects ORDER BY created_at DESC")
277-
rows = cur.fetchall()
278-
return [dict(row) for row in rows]
279-
finally:
280-
conn.close()
280+
281+
def _list():
282+
conn = sqlite3.connect(registry_path, timeout=10.0)
283+
conn.row_factory = sqlite3.Row
284+
try:
285+
cur = conn.cursor()
286+
cur.execute("SELECT * FROM projects ORDER BY created_at DESC")
287+
rows = cur.fetchall()
288+
return [dict(row) for row in rows]
289+
finally:
290+
conn.close()
291+
292+
return _retry_on_db_locked(_list)
281293

282294

283295
def update_project_status(project_id: str, status: str, last_indexed_at: Optional[str] = None):
@@ -292,22 +304,26 @@ def update_project_status(project_id: str, status: str, last_indexed_at: Optiona
292304
_init_registry_db()
293305

294306
registry_path = _get_projects_registry_path()
295-
conn = sqlite3.connect(registry_path)
296-
try:
297-
cur = conn.cursor()
298-
if last_indexed_at:
299-
cur.execute(
300-
"UPDATE projects SET status = ?, last_indexed_at = ? WHERE id = ?",
301-
(status, last_indexed_at, project_id)
302-
)
303-
else:
304-
cur.execute(
305-
"UPDATE projects SET status = ? WHERE id = ?",
306-
(status, project_id)
307-
)
308-
conn.commit()
309-
finally:
310-
conn.close()
307+
308+
def _update():
309+
conn = sqlite3.connect(registry_path, timeout=10.0)
310+
try:
311+
cur = conn.cursor()
312+
if last_indexed_at:
313+
cur.execute(
314+
"UPDATE projects SET status = ?, last_indexed_at = ? WHERE id = ?",
315+
(status, last_indexed_at, project_id)
316+
)
317+
else:
318+
cur.execute(
319+
"UPDATE projects SET status = ? WHERE id = ?",
320+
(status, project_id)
321+
)
322+
conn.commit()
323+
finally:
324+
conn.close()
325+
326+
_retry_on_db_locked(_update)
311327

312328

313329
def update_project_settings(project_id: str, settings: Dict[str, Any]):
@@ -321,16 +337,20 @@ def update_project_settings(project_id: str, settings: Dict[str, Any]):
321337
_init_registry_db()
322338

323339
registry_path = _get_projects_registry_path()
324-
conn = sqlite3.connect(registry_path)
325-
try:
326-
cur = conn.cursor()
327-
cur.execute(
328-
"UPDATE projects SET settings = ? WHERE id = ?",
329-
(json.dumps(settings), project_id)
330-
)
331-
conn.commit()
332-
finally:
333-
conn.close()
340+
341+
def _update():
342+
conn = sqlite3.connect(registry_path, timeout=10.0)
343+
try:
344+
cur = conn.cursor()
345+
cur.execute(
346+
"UPDATE projects SET settings = ? WHERE id = ?",
347+
(json.dumps(settings), project_id)
348+
)
349+
conn.commit()
350+
finally:
351+
conn.close()
352+
353+
_retry_on_db_locked(_update)
334354

335355

336356
def delete_project(project_id: str):
@@ -357,13 +377,17 @@ def delete_project(project_id: str):
357377

358378
# Remove from registry
359379
registry_path = _get_projects_registry_path()
360-
conn = sqlite3.connect(registry_path)
361-
try:
362-
cur = conn.cursor()
363-
cur.execute("DELETE FROM projects WHERE id = ?", (project_id,))
364-
conn.commit()
365-
finally:
366-
conn.close()
380+
381+
def _delete():
382+
conn = sqlite3.connect(registry_path, timeout=10.0)
383+
try:
384+
cur = conn.cursor()
385+
cur.execute("DELETE FROM projects WHERE id = ?", (project_id,))
386+
conn.commit()
387+
finally:
388+
conn.close()
389+
390+
_retry_on_db_locked(_delete)
367391

368392

369393
def get_or_create_project(project_path: str, name: Optional[str] = None) -> Dict[str, Any]:

0 commit comments

Comments
 (0)