mirror of
https://github.com/Comfy-Org/ComfyUI-Manager.git
synced 2026-04-04 15:46:41 +08:00
fix(core): harden try_rmtree with retry and rename for Windows
Some checks failed
Python Linting / Run Ruff (push) Has been cancelled
CI / Validate OpenAPI Specification (push) Has been cancelled
CI / Code Quality Checks (push) Has been cancelled
E2E Tests on Multiple Platforms / E2E (${{ matrix.os }}, py${{ matrix.python-version }}) (macos-latest, 3.10) (push) Has been cancelled
E2E Tests on Multiple Platforms / E2E (${{ matrix.os }}, py${{ matrix.python-version }}) (ubuntu-latest, 3.10) (push) Has been cancelled
E2E Tests on Multiple Platforms / E2E (${{ matrix.os }}, py${{ matrix.python-version }}) (windows-latest, 3.10) (push) Has been cancelled
Some checks failed
Python Linting / Run Ruff (push) Has been cancelled
CI / Validate OpenAPI Specification (push) Has been cancelled
CI / Code Quality Checks (push) Has been cancelled
E2E Tests on Multiple Platforms / E2E (${{ matrix.os }}, py${{ matrix.python-version }}) (macos-latest, 3.10) (push) Has been cancelled
E2E Tests on Multiple Platforms / E2E (${{ matrix.os }}, py${{ matrix.python-version }}) (ubuntu-latest, 3.10) (push) Has been cancelled
E2E Tests on Multiple Platforms / E2E (${{ matrix.os }}, py${{ matrix.python-version }}) (windows-latest, 3.10) (push) Has been cancelled
On Windows, shutil.rmtree fails when files are locked by antivirus or git handles. The current fallback (reserve_script for lazy delete) is useless in cm-cli where there is no restart cycle, causing reinstall to fail with "Already exists". 3-tier deletion strategy: 1. Retry rmtree 3x with 1s delay (handles transient locks) 2. Rename to .trash_* then delete (moves out of scan path) 3. Lazy delete via reserve_script (ComfyUI GUI fallback) After rename, lazy-delete targets the .trash_* path (not original), so the original path is clear for subsequent clone/install.
This commit is contained in:
parent
41ab628f99
commit
df00805bee
@ -1854,11 +1854,32 @@ def reserve_script(repo_path, install_cmds):
|
||||
|
||||
|
||||
def try_rmtree(title, fullpath):
|
||||
# Tier 1: retry with delay for transient Windows file locks
|
||||
for attempt in range(3):
|
||||
try:
|
||||
shutil.rmtree(fullpath)
|
||||
return
|
||||
except OSError:
|
||||
if attempt < 2:
|
||||
time.sleep(1)
|
||||
|
||||
# Tier 2: rename out of scan path so clone/install can proceed
|
||||
trash = fullpath + f'.trash_{uuid.uuid4().hex[:8]}'
|
||||
try:
|
||||
shutil.rmtree(fullpath)
|
||||
except Exception as e:
|
||||
logging.warning(f"[ComfyUI-Manager] An error occurred while deleting '{fullpath}', so it has been scheduled for deletion upon restart.\nEXCEPTION: {e}")
|
||||
reserve_script(title, ["#LAZY-DELETE-NODEPACK", fullpath])
|
||||
os.rename(fullpath, trash)
|
||||
shutil.rmtree(trash, ignore_errors=True)
|
||||
if not os.path.exists(trash):
|
||||
return
|
||||
# Rename succeeded but delete failed — schedule trash path for lazy delete
|
||||
logging.warning(f"[ComfyUI-Manager] Renamed '{fullpath}' to '{trash}' but could not delete; scheduled for restart.")
|
||||
reserve_script(title, ["#LAZY-DELETE-NODEPACK", trash])
|
||||
return
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
# Tier 3: lazy delete on restart (ComfyUI GUI fallback)
|
||||
logging.warning(f"[ComfyUI-Manager] An error occurred while deleting '{fullpath}', so it has been scheduled for deletion upon restart.")
|
||||
reserve_script(title, ["#LAZY-DELETE-NODEPACK", fullpath])
|
||||
|
||||
|
||||
def try_install_script(url, repo_path, install_cmd, instant_execution=False):
|
||||
|
||||
@ -1833,11 +1833,32 @@ def reserve_script(repo_path, install_cmds):
|
||||
|
||||
|
||||
def try_rmtree(title, fullpath):
|
||||
# Tier 1: retry with delay for transient Windows file locks
|
||||
for attempt in range(3):
|
||||
try:
|
||||
shutil.rmtree(fullpath)
|
||||
return
|
||||
except OSError:
|
||||
if attempt < 2:
|
||||
time.sleep(1)
|
||||
|
||||
# Tier 2: rename out of scan path so clone/install can proceed
|
||||
trash = fullpath + f'.trash_{uuid.uuid4().hex[:8]}'
|
||||
try:
|
||||
shutil.rmtree(fullpath)
|
||||
except Exception as e:
|
||||
logging.warning(f"[ComfyUI-Manager] An error occurred while deleting '{fullpath}', so it has been scheduled for deletion upon restart.\nEXCEPTION: {e}")
|
||||
reserve_script(title, ["#LAZY-DELETE-NODEPACK", fullpath])
|
||||
os.rename(fullpath, trash)
|
||||
shutil.rmtree(trash, ignore_errors=True)
|
||||
if not os.path.exists(trash):
|
||||
return
|
||||
# Rename succeeded but delete failed — schedule trash path for lazy delete
|
||||
logging.warning(f"[ComfyUI-Manager] Renamed '{fullpath}' to '{trash}' but could not delete; scheduled for restart.")
|
||||
reserve_script(title, ["#LAZY-DELETE-NODEPACK", trash])
|
||||
return
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
# Tier 3: lazy delete on restart (ComfyUI GUI fallback)
|
||||
logging.warning(f"[ComfyUI-Manager] An error occurred while deleting '{fullpath}', so it has been scheduled for deletion upon restart.")
|
||||
reserve_script(title, ["#LAZY-DELETE-NODEPACK", fullpath])
|
||||
|
||||
|
||||
def try_install_script(url, repo_path, install_cmd, instant_execution=False):
|
||||
|
||||
Loading…
Reference in New Issue
Block a user