Remove rows where owner PID is dead. Args: lock_name: Name identifying the lock Returns: True if any stale locks were removed
(self, lock_name: str)
| 275 | return True |
| 276 | |
| 277 | def break_stale_lock(self, lock_name: str) -> bool: |
| 278 | """Remove rows where owner PID is dead. |
| 279 | |
| 280 | Args: |
| 281 | lock_name: Name identifying the lock |
| 282 | |
| 283 | Returns: |
| 284 | True if any stale locks were removed |
| 285 | """ |
| 286 | holders = self.get_lock_info(lock_name) |
| 287 | if not holders: |
| 288 | return False |
| 289 | |
| 290 | removed = False |
| 291 | conn = self._get_connection() |
| 292 | try: |
| 293 | cursor = conn.cursor() |
| 294 | for holder in holders: |
| 295 | pid = holder["owner_pid"] |
| 296 | if not is_process_alive(pid): |
| 297 | cursor.execute( |
| 298 | "DELETE FROM lock_holders WHERE lock_name = ? AND owner_pid = ?", |
| 299 | (lock_name, pid), |
| 300 | ) |
| 301 | if cursor.rowcount > 0: |
| 302 | removed = True |
| 303 | logger.info(f"Broke stale lock: {lock_name} (dead PID {pid})") |
| 304 | conn.commit() |
| 305 | finally: |
| 306 | conn.close() |
| 307 | |
| 308 | return removed |
| 309 | |
| 310 | def force_break(self, lock_name: str) -> bool: |
| 311 | """Unconditionally remove all holders for a lock. |