2023-06-03 07:36:24 -07:00
|
|
|
import os
|
|
|
|
import sys
|
|
|
|
import importlib.util
|
|
|
|
|
|
|
|
class AlreadyRunningError(Exception):
|
|
|
|
def __init__(self, message: str=""):
|
|
|
|
self.message = message
|
|
|
|
super().__init__(self.message)
|
|
|
|
def __str__(self):
|
|
|
|
return self.message
|
|
|
|
|
|
|
|
|
|
|
|
LOCK_FILENAME = '_uploading.lock'
|
|
|
|
|
|
|
|
class UploadLock_Basic:
|
|
|
|
def __init__(self, lock_dir):
|
|
|
|
self.lock_file = os.path.join(lock_dir, LOCK_FILENAME)
|
|
|
|
|
|
|
|
def __enter__(self):
|
|
|
|
if os.path.exists(self.lock_file):
|
|
|
|
with open(self.lock_file, 'r', encoding='utf-8') as f:
|
|
|
|
print(f.read())
|
|
|
|
print("Another instance is already running.")
|
|
|
|
raise AlreadyRunningError('Another instance is already running.')
|
|
|
|
else:
|
|
|
|
with open(self.lock_file, 'w', encoding='utf-8') as f:
|
|
|
|
f.write(f'PID: {os.getpid()}: Running')
|
2023-06-03 08:49:58 -07:00
|
|
|
# print("Acquired lock, continuing.")
|
2023-06-03 07:36:24 -07:00
|
|
|
|
|
|
|
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
|
|
os.remove(self.lock_file)
|
2023-06-03 08:49:58 -07:00
|
|
|
# print("Released lock.")
|
2023-06-03 07:36:24 -07:00
|
|
|
|
|
|
|
# decorator
|
|
|
|
def __call__(self, func):
|
|
|
|
def wrapper(*args, **kwargs):
|
|
|
|
with self:
|
|
|
|
return func(*args, **kwargs)
|
|
|
|
return wrapper
|
|
|
|
|
|
|
|
|
|
|
|
class UploadLock_Fcntl():
|
|
|
|
fcntl = None
|
|
|
|
try:
|
|
|
|
import fcntl
|
|
|
|
except ModuleNotFoundError:
|
|
|
|
pass
|
|
|
|
|
|
|
|
def __init__(self, lock_dir):
|
|
|
|
if self.fcntl is None:
|
|
|
|
raise(ModuleNotFoundError("No module named 'fcntl'", name='fcntl'))
|
|
|
|
|
|
|
|
self.lock_file = os.path.join(lock_dir, LOCK_FILENAME)
|
|
|
|
self.lock_file_fd = None
|
|
|
|
|
|
|
|
def __enter__(self):
|
|
|
|
self.lock_file_fd = open(self.lock_file, 'w')
|
|
|
|
try:
|
|
|
|
self.fcntl.lockf(self.lock_file_fd, self.fcntl.LOCK_EX | self.fcntl.LOCK_NB)
|
2023-06-03 08:49:58 -07:00
|
|
|
# print("Acquired lock, continuing.")
|
2023-06-03 07:36:24 -07:00
|
|
|
except IOError:
|
|
|
|
raise AlreadyRunningError("Another instance is already running.")
|
|
|
|
|
|
|
|
|
|
|
|
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
|
|
if self.lock_file_fd is None:
|
|
|
|
raise IOError("Lock file not opened.")
|
|
|
|
self.fcntl.lockf(self.lock_file_fd, self.fcntl.LOCK_UN)
|
|
|
|
self.lock_file_fd.close()
|
|
|
|
os.remove(self.lock_file)
|
2023-06-03 08:49:58 -07:00
|
|
|
# print("Released lock.")
|
2023-06-03 07:36:24 -07:00
|
|
|
|
|
|
|
# decorator
|
|
|
|
def __call__(self, func):
|
|
|
|
def wrapper(*args, **kwargs):
|
|
|
|
with self:
|
|
|
|
return func(*args, **kwargs)
|
|
|
|
return wrapper
|
|
|
|
|
|
|
|
class UploadLock():
|
|
|
|
def __new__(cls, lock_dir):
|
|
|
|
fcntl_avaivable = importlib.util.find_spec('fcntl')
|
|
|
|
if fcntl_avaivable is not None:
|
|
|
|
return UploadLock_Fcntl(lock_dir)
|
|
|
|
else:
|
|
|
|
return UploadLock_Basic(lock_dir)
|