Skip to content

Commit

Permalink
New file lock implementation using flock()
Browse files Browse the repository at this point in the history
Hopefully this should avoid some of the race conditions observed when
using the softer file lock.

Refs #620
  • Loading branch information
coleifer committed Sep 15, 2021
1 parent 9b0ce1a commit 2166341
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 13 deletions.
2 changes: 1 addition & 1 deletion huey/tests/test_storage.py
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ def tearDown(self):

def get_huey(self):
return Huey('test-file-storage', storage_class=FileStorage,
path=self.path, levels=2)
path=self.path, levels=2, use_thread_lock=True)

def test_filesystem_result_store(self):
s = self.huey.storage
Expand Down
27 changes: 15 additions & 12 deletions huey/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@
import os
import sys
import time
import warnings
try:
import fcntl
except ImportError:
fcntl = None


Error = namedtuple('Error', ('metadata',))
Expand Down Expand Up @@ -130,9 +135,11 @@ def decode(s):


class FileLock(object):
def __init__(self, filename, interval=0.01):
def __init__(self, filename):
if fcntl is None:
warnings.warn('FileLock not supported on this platform. Please '
'use a different storage implementation.')
self.filename = filename
self.interval = interval
self.fd = None

dirname = os.path.dirname(filename)
Expand All @@ -142,21 +149,17 @@ def __init__(self, filename, interval=0.01):
os.unlink(self.filename)

def acquire(self):
flags = os.O_CREAT | os.O_EXCL | os.O_RDWR
while True:
try:
self.fd = os.open(self.filename, flags)
break
except OSError as exc:
if exc.errno != errno.EEXIST:
raise
time.sleep(self.interval)
flags = os.O_CREAT | os.O_TRUNC | os.O_RDWR
self.fd = os.open(self.filename, flags)
if fcntl is not None:
fcntl.flock(self.fd, fcntl.LOCK_EX)

def release(self):
if self.fd is not None:
fd, self.fd = self.fd, None
if fcntl is not None:
fcntl.flock(fd, fcntl.LOCK_UN)
os.close(fd)
os.unlink(self.filename)

def __enter__(self):
self.acquire()
Expand Down

0 comments on commit 2166341

Please sign in to comment.