Publish curated Unraid-AppOps-Gateway source from 84f2a9958b2bdf1c1c13553925026d75f32703c3
This commit is contained in:
1 parent
8dd4b40252
commit
5d598db0df
14 files changed
+2765
-46
No files matched your search
@@ -42,13 +42,19 @@ def _sha(value: str) -> str:
|
||||
return hashlib.sha256(value.encode("ascii")).hexdigest()
|
||||
|
||||
|
||||
def _second_process_lock(path_text, started, locked):
|
||||
def _second_process_lock(path_text, ready, attempt, attempting, acquired):
|
||||
import fcntl
|
||||
|
||||
started.set()
|
||||
# Separate process startup from the lock attempt. In particular, the
|
||||
# parent must not hold the project lock while waiting for multiprocessing
|
||||
# to import this test module (which can be slow under forkserver on /mnt/c).
|
||||
ready.set()
|
||||
if not attempt.wait(15):
|
||||
return
|
||||
attempting.set()
|
||||
with open(path_text, "a+") as handle:
|
||||
fcntl.flock(handle, fcntl.LOCK_EX)
|
||||
locked.set()
|
||||
acquired.set()
|
||||
fcntl.flock(handle, fcntl.LOCK_UN)
|
||||
|
||||
|
||||
@@ -807,20 +813,35 @@ def test_transaction_rejects_other_thread_store_calls_and_transactions(store_env
|
||||
def test_project_flock_blocks_a_second_process(store_env):
|
||||
module, store, _controller, _state = store_env
|
||||
ready = multiprocessing.Event()
|
||||
attempt = multiprocessing.Event()
|
||||
attempting = multiprocessing.Event()
|
||||
acquired = multiprocessing.Event()
|
||||
|
||||
with store.transaction():
|
||||
assert store.load_intent() is None
|
||||
child = multiprocessing.Process(
|
||||
target=_second_process_lock,
|
||||
args=(str(module.PROJECT_LOCK), ready, acquired),
|
||||
)
|
||||
child.start()
|
||||
assert ready.wait(2)
|
||||
assert not acquired.wait(0.1)
|
||||
assert acquired.wait(2)
|
||||
child.join(timeout=2)
|
||||
assert child.exitcode == 0
|
||||
child = multiprocessing.Process(
|
||||
target=_second_process_lock,
|
||||
args=(str(module.PROJECT_LOCK), ready, attempt, attempting, acquired),
|
||||
)
|
||||
child.start()
|
||||
try:
|
||||
# Give process creation/import a bounded interval while no lock is held.
|
||||
assert ready.wait(15), f"lock contender did not start (exit={child.exitcode})"
|
||||
with store.transaction():
|
||||
assert store.load_intent() is None
|
||||
attempt.set()
|
||||
assert attempting.wait(5), (
|
||||
f"lock contender did not attempt acquisition (exit={child.exitcode})"
|
||||
)
|
||||
assert not acquired.wait(0.1)
|
||||
assert acquired.wait(5)
|
||||
child.join(timeout=5)
|
||||
assert child.exitcode == 0
|
||||
finally:
|
||||
# Let a child blocked on the handshake exit on assertion failures too.
|
||||
attempt.set()
|
||||
child.join(timeout=5)
|
||||
if child.is_alive():
|
||||
child.terminate()
|
||||
child.join(timeout=5)
|
||||
|
||||
|
||||
def _registered_recovery(store, restore, *, preserve=True, reason="target_health_failed"):
|
||||
|
||||
Reference in new issue
Block a user