Skip to content

Commit 5b67463

Browse files
Improve routine lock. (#298)
* Improve routine lock. * Add PID to .lock file.
1 parent b81181d commit 5b67463

File tree

1 file changed

+42
-5
lines changed

1 file changed

+42
-5
lines changed

src/admin.py

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
import json
2626
import logging
27+
import os
2728
import random
2829
import time
2930
import zipfile
@@ -274,19 +275,33 @@ def refresh_has_metakg():
274275
smartapi.save()
275276

276277

278+
def get_lock_pid():
279+
"""Read PID from lock file if it exists"""
280+
lock_file_path = ".lock"
281+
if os.path.exists(lock_file_path):
282+
try:
283+
with open(lock_file_path, "r") as f:
284+
pid = f.read().strip()
285+
return int(pid) if pid.isdigit() else None
286+
except Exception as e:
287+
logging.warning(f"Could not read PID from {lock_file_path}: {e}")
288+
return None
289+
return None
290+
291+
277292
restore = restore_from_file
278293
backup = backup_to_file
279294

280295
refresh = refresh_document
281296
check = check_uptime
282297

283-
# only one process should perform backup routines
284-
_lock = FileLock(".lock", timeout=0)
285-
286298

287299
def routine(no_backup=False, format="zip"):
288300
logger = logging.getLogger("routine")
289301

302+
# only one process should perform backup routines
303+
_lock = FileLock(".lock", timeout=0)
304+
290305
# Add jitter: random delay between 100 and 500 milliseconds (adjust range as needed)
291306
jitter_ms = random.uniform(100, 500) # Jitter in milliseconds
292307
jitter_seconds = jitter_ms / 1000 # Convert milliseconds to seconds
@@ -300,7 +315,11 @@ def routine(no_backup=False, format="zip"):
300315
# it won't block here
301316
lock_acquired = _lock.acquire()
302317
if lock_acquired:
303-
logger.info("Schedule lock acquired successfully.")
318+
# Write PID to the lock file
319+
current_pid = os.getpid()
320+
with open(".lock", "w") as lock_file:
321+
lock_file.write(str(current_pid))
322+
logger.info(f"Schedule lock acquired successfully. PID {current_pid} written to lock file.")
304323
if not no_backup:
305324
logger.info(f"backup_to_s3(format={format})")
306325
backup_to_s3(format=format)
@@ -317,7 +336,11 @@ def routine(no_backup=False, format="zip"):
317336
else:
318337
logger.warning("Schedule lock acquired by another process. No need to run it in this process.")
319338
except Timeout:
320-
logger.warning("Schedule lock acquired by another process. No need to run it in this process.")
339+
existing_pid = get_lock_pid()
340+
if existing_pid:
341+
logger.warning(f"Schedule lock acquired by another process (PID: {existing_pid}). No need to run it in this process.")
342+
else:
343+
logger.warning("Schedule lock acquired by another process. No need to run it in this process.")
321344
except Exception as e:
322345
logger.error(f"An error occurred during the routine: {e}")
323346
logger.error("Stack trace:", exc_info=True)
@@ -326,6 +349,20 @@ def routine(no_backup=False, format="zip"):
326349
_lock.release()
327350
logger.info("Schedule lock released successfully.")
328351

352+
# Try to delete the .lock file manually if it still exists
353+
lock_file_path = ".lock"
354+
if os.path.exists(lock_file_path):
355+
try:
356+
# Log the PID that was in the lock file before deletion
357+
existing_pid = get_lock_pid()
358+
os.remove(lock_file_path)
359+
if existing_pid:
360+
logger.info(f".lock file manually deleted (contained PID: {existing_pid}).")
361+
else:
362+
logger.info(".lock file manually deleted.")
363+
except Exception as e:
364+
logger.warning(f"Could not delete .lock file: {e}")
365+
329366

330367
if __name__ == "__main__":
331368
restore_from_s3()

0 commit comments

Comments
 (0)