mirror of
https://github.com/willmiao/ComfyUI-Lora-Manager.git
synced 2026-07-09 02:41:17 -03:00
Compare commits
3 Commits
a5c861646c
...
138024aefe
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
138024aefe | ||
|
|
a19ddc14f6 | ||
|
|
7001ced694 |
@@ -13,7 +13,7 @@ from ...config import config as global_config
|
|||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
_CHUNK_SIZE = 256 * 1024 # 256 KB
|
_CHUNK_SIZE = 1024 * 1024 # 1 MB — balance between streaming iteration overhead and per-chunk memory
|
||||||
|
|
||||||
# Video file extensions that bypass native sendfile on Windows
|
# Video file extensions that bypass native sendfile on Windows
|
||||||
# to avoid IOCP/ProactorEventLoop crashes during client disconnect.
|
# to avoid IOCP/ProactorEventLoop crashes during client disconnect.
|
||||||
@@ -55,15 +55,11 @@ class PreviewHandler:
|
|||||||
logger.debug("Preview file not found at %s", str(resolved))
|
logger.debug("Preview file not found at %s", str(resolved))
|
||||||
raise web.HTTPNotFound(text="Preview file not found")
|
raise web.HTTPNotFound(text="Preview file not found")
|
||||||
|
|
||||||
# Video files: stream manually to avoid Windows native sendfile crash.
|
# aiohttp's FileResponse handles range requests, content headers, and
|
||||||
# aiohttp's FileResponse uses _sendfile_native on Windows (IOCP-based),
|
# uses kernel sendfile (zero-copy DMA) on Linux/macOS. On Windows it
|
||||||
# which breaks when the client disconnects mid-transfer — this happens
|
# uses IOCP-based _sendfile_native which can crash when the client
|
||||||
# constantly when users scroll through a gallery of animated previews.
|
# disconnects mid-transfer during fast scrolling. The _stream_file()
|
||||||
suffix = resolved.suffix.lower()
|
# fallback is kept for a future compat toggle.
|
||||||
if suffix in _VIDEO_EXTENSIONS:
|
|
||||||
return await self._stream_file(request, resolved)
|
|
||||||
|
|
||||||
# aiohttp's FileResponse handles range requests and content headers for us.
|
|
||||||
return web.FileResponse(path=resolved, chunk_size=_CHUNK_SIZE)
|
return web.FileResponse(path=resolved, chunk_size=_CHUNK_SIZE)
|
||||||
|
|
||||||
async def _stream_file(
|
async def _stream_file(
|
||||||
@@ -83,6 +79,10 @@ class PreviewHandler:
|
|||||||
resp.content_type = content_type
|
resp.content_type = content_type
|
||||||
resp.content_length = file_size
|
resp.content_length = file_size
|
||||||
|
|
||||||
|
# Allow browser caching: video previews rarely change during a session.
|
||||||
|
# The frontend already appends ?t={version} to bust cache on update.
|
||||||
|
resp.headers["Cache-Control"] = "public, max-age=86400"
|
||||||
|
|
||||||
await resp.prepare(request)
|
await resp.prepare(request)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|||||||
@@ -81,7 +81,11 @@ class _RateLimitRetryHelper:
|
|||||||
|
|
||||||
def _calculate_delay(self, retry_after: Optional[float], attempt: int) -> float:
|
def _calculate_delay(self, retry_after: Optional[float], attempt: int) -> float:
|
||||||
if retry_after is not None:
|
if retry_after is not None:
|
||||||
return min(self._max_delay, max(0.0, retry_after))
|
# Cap at 1800s (30 min) as a safety ceiling. The old 30s cap was
|
||||||
|
# too low — CivArchive can return retry_after ~1500s, causing all
|
||||||
|
# retries to fail. A generous ceiling protects against pathological
|
||||||
|
# server values while still respecting the server's guidance.
|
||||||
|
return min(1800.0, max(0.0, retry_after))
|
||||||
|
|
||||||
base_delay = self._base_delay * (2 ** max(0, attempt - 1))
|
base_delay = self._base_delay * (2 ** max(0, attempt - 1))
|
||||||
jitter_span = base_delay * self._jitter_ratio
|
jitter_span = base_delay * self._jitter_ratio
|
||||||
|
|||||||
Reference in New Issue
Block a user