Sleep for longer at a time in lock_path.
When lock_path is called and the lock goes for the whole 10 seconds, the flock is called 1000 times. With this patch, the short 0.01 sleep is used for the first 1% of the total lock time and then 1% of the total lock time is used. Change-Id: Ibed6bdb49bddcdb868742c41f86d2482a7edfd29
This commit is contained in:
parent
698919e67b
commit
a0e0014159
@ -1600,6 +1600,10 @@ def lock_path(directory, timeout=10, timeout_class=None):
|
|||||||
mkdirs(directory)
|
mkdirs(directory)
|
||||||
lockpath = '%s/.lock' % directory
|
lockpath = '%s/.lock' % directory
|
||||||
fd = os.open(lockpath, os.O_WRONLY | os.O_CREAT)
|
fd = os.open(lockpath, os.O_WRONLY | os.O_CREAT)
|
||||||
|
sleep_time = 0.01
|
||||||
|
slower_sleep_time = max(timeout * 0.01, sleep_time)
|
||||||
|
slowdown_at = timeout * 0.01
|
||||||
|
time_slept = 0
|
||||||
try:
|
try:
|
||||||
with timeout_class(timeout, lockpath):
|
with timeout_class(timeout, lockpath):
|
||||||
while True:
|
while True:
|
||||||
@ -1609,7 +1613,10 @@ def lock_path(directory, timeout=10, timeout_class=None):
|
|||||||
except IOError as err:
|
except IOError as err:
|
||||||
if err.errno != errno.EAGAIN:
|
if err.errno != errno.EAGAIN:
|
||||||
raise
|
raise
|
||||||
sleep(0.01)
|
if time_slept > slowdown_at:
|
||||||
|
sleep_time = slower_sleep_time
|
||||||
|
sleep(sleep_time)
|
||||||
|
time_slept += sleep_time
|
||||||
yield True
|
yield True
|
||||||
finally:
|
finally:
|
||||||
os.close(fd)
|
os.close(fd)
|
||||||
|
@ -727,6 +727,30 @@ class TestUtils(unittest.TestCase):
|
|||||||
finally:
|
finally:
|
||||||
shutil.rmtree(tmpdir)
|
shutil.rmtree(tmpdir)
|
||||||
|
|
||||||
|
def test_lock_path_num_sleeps(self):
|
||||||
|
tmpdir = mkdtemp()
|
||||||
|
num_short_calls = [0]
|
||||||
|
exception_raised = [False]
|
||||||
|
|
||||||
|
def my_sleep(to_sleep):
|
||||||
|
if to_sleep == 0.01:
|
||||||
|
num_short_calls[0] += 1
|
||||||
|
else:
|
||||||
|
raise Exception('sleep time changed: %s' % to_sleep)
|
||||||
|
|
||||||
|
try:
|
||||||
|
with mock.patch('swift.common.utils.sleep', my_sleep):
|
||||||
|
with utils.lock_path(tmpdir):
|
||||||
|
with utils.lock_path(tmpdir):
|
||||||
|
pass
|
||||||
|
except Exception as e:
|
||||||
|
exception_raised[0] = True
|
||||||
|
self.assertTrue('sleep time changed' in str(e))
|
||||||
|
finally:
|
||||||
|
shutil.rmtree(tmpdir)
|
||||||
|
self.assertEqual(num_short_calls[0], 11)
|
||||||
|
self.assertTrue(exception_raised[0])
|
||||||
|
|
||||||
def test_lock_path_class(self):
|
def test_lock_path_class(self):
|
||||||
tmpdir = mkdtemp()
|
tmpdir = mkdtemp()
|
||||||
try:
|
try:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user