Remove all lock rows where owner PID is dead. Returns: Number of stale lock rows removed
(self)
| 358 | conn.close() |
| 359 | |
| 360 | def cleanup_stale_locks(self) -> int: |
| 361 | """Remove all lock rows where owner PID is dead. |
| 362 | |
| 363 | Returns: |
| 364 | Number of stale lock rows removed |
| 365 | """ |
| 366 | all_locks = self.list_all_locks() |
| 367 | if not all_locks: |
| 368 | return 0 |
| 369 | |
| 370 | removed_count = 0 |
| 371 | conn = self._get_connection() |
| 372 | try: |
| 373 | cursor = conn.cursor() |
| 374 | for lock in all_locks: |
| 375 | pid = lock["owner_pid"] |
| 376 | if not is_process_alive(pid): |
| 377 | cursor.execute( |
| 378 | "DELETE FROM lock_holders WHERE lock_name = ? AND owner_pid = ?", |
| 379 | (lock["lock_name"], pid), |
| 380 | ) |
| 381 | if cursor.rowcount > 0: |
| 382 | removed_count += 1 |
| 383 | logger.info( |
| 384 | f"Cleaned stale lock: {lock['lock_name']} (dead PID {pid})" |
| 385 | ) |
| 386 | conn.commit() |
| 387 | finally: |
| 388 | conn.close() |
| 389 | |
| 390 | return removed_count |
| 391 | |
| 392 | def force_break_all(self) -> int: |
| 393 | """Unconditionally remove all lock records. |