remove unnecessary DOWNLOAD_MODE config; always run concurrently (can limit to 1 for sequential mode)
This commit is contained in:
@@ -33,12 +33,7 @@ Certain values can be set via environment variables, using the `-e` parameter on
|
|||||||
|
|
||||||
### ⬇️ Download Behavior
|
### ⬇️ Download Behavior
|
||||||
|
|
||||||
* __DOWNLOAD_MODE__: This flag controls how downloads are scheduled and executed. Options are `sequential`, `concurrent`, and `limited`. Defaults to `limited`:
|
* __MAX_CONCURRENT_DOWNLOADS__: Maximum number of simultaneous downloads allowed. For example, if set to `5`, then at most five downloads will run concurrently, and any additional downloads will wait until one of the active downloads completes. Defaults to `3`.
|
||||||
* `sequential`: Downloads are processed one at a time. A new download won't start until the previous one has finished. This mode is useful for conserving system resources or ensuring downloads occur in strict order.
|
|
||||||
* `concurrent`: Downloads are started immediately as they are added, with no built-in limit on how many run simultaneously. This mode may overwhelm your system if too many downloads start at once.
|
|
||||||
* `limited`: Downloads are started concurrently but are capped by a concurrency limit. In this mode, a semaphore is used so that at most a fixed number of downloads run at any given time.
|
|
||||||
* __MAX_CONCURRENT_DOWNLOADS__: This flag is used only when `DOWNLOAD_MODE` is set to `limited`.
|
|
||||||
It specifies the maximum number of simultaneous downloads allowed. For example, if set to `5`, then at most five downloads will run concurrently, and any additional downloads will wait until one of the active downloads completes. Defaults to `3`.
|
|
||||||
* __DELETE_FILE_ON_TRASHCAN__: if `true`, downloaded files are deleted on the server, when they are trashed from the "Completed" section of the UI. Defaults to `false`.
|
* __DELETE_FILE_ON_TRASHCAN__: if `true`, downloaded files are deleted on the server, when they are trashed from the "Completed" section of the UI. Defaults to `false`.
|
||||||
* __DEFAULT_OPTION_PLAYLIST_ITEM_LIMIT__: Maximum number of playlist items that can be downloaded. Defaults to `0` (no limit).
|
* __DEFAULT_OPTION_PLAYLIST_ITEM_LIMIT__: Maximum number of playlist items that can be downloaded. Defaults to `0` (no limit).
|
||||||
|
|
||||||
|
|||||||
@@ -69,7 +69,6 @@ class Config:
|
|||||||
'KEYFILE': '',
|
'KEYFILE': '',
|
||||||
'BASE_DIR': '',
|
'BASE_DIR': '',
|
||||||
'DEFAULT_THEME': 'auto',
|
'DEFAULT_THEME': 'auto',
|
||||||
'DOWNLOAD_MODE': 'limited',
|
|
||||||
'MAX_CONCURRENT_DOWNLOADS': 3,
|
'MAX_CONCURRENT_DOWNLOADS': 3,
|
||||||
'LOGLEVEL': 'INFO',
|
'LOGLEVEL': 'INFO',
|
||||||
'ENABLE_ACCESSLOG': 'false',
|
'ENABLE_ACCESSLOG': 'false',
|
||||||
|
|||||||
37
app/ytdl.py
37
app/ytdl.py
@@ -364,13 +364,7 @@ class DownloadQueue:
|
|||||||
self.done = PersistentQueue("completed", self.config.STATE_DIR + '/completed')
|
self.done = PersistentQueue("completed", self.config.STATE_DIR + '/completed')
|
||||||
self.pending = PersistentQueue("pending", self.config.STATE_DIR + '/pending')
|
self.pending = PersistentQueue("pending", self.config.STATE_DIR + '/pending')
|
||||||
self.active_downloads = set()
|
self.active_downloads = set()
|
||||||
self.semaphore = None
|
self.semaphore = asyncio.Semaphore(int(self.config.MAX_CONCURRENT_DOWNLOADS))
|
||||||
# For sequential mode, use an asyncio lock to ensure one-at-a-time execution.
|
|
||||||
if self.config.DOWNLOAD_MODE == 'sequential':
|
|
||||||
self.seq_lock = asyncio.Lock()
|
|
||||||
elif self.config.DOWNLOAD_MODE == 'limited':
|
|
||||||
self.semaphore = asyncio.Semaphore(int(self.config.MAX_CONCURRENT_DOWNLOADS))
|
|
||||||
|
|
||||||
self.done.load()
|
self.done.load()
|
||||||
|
|
||||||
async def __import_queue(self):
|
async def __import_queue(self):
|
||||||
@@ -390,31 +384,12 @@ class DownloadQueue:
|
|||||||
if download.canceled:
|
if download.canceled:
|
||||||
log.info(f"Download {download.info.title} was canceled, skipping start.")
|
log.info(f"Download {download.info.title} was canceled, skipping start.")
|
||||||
return
|
return
|
||||||
if self.config.DOWNLOAD_MODE == 'sequential':
|
|
||||||
async with self.seq_lock:
|
|
||||||
log.info("Starting sequential download.")
|
|
||||||
await download.start(self.notifier)
|
|
||||||
self._post_download_cleanup(download)
|
|
||||||
elif self.config.DOWNLOAD_MODE == 'limited' and self.semaphore is not None:
|
|
||||||
await self.__limited_concurrent_download(download)
|
|
||||||
else:
|
|
||||||
await self.__concurrent_download(download)
|
|
||||||
|
|
||||||
async def __concurrent_download(self, download):
|
|
||||||
log.info("Starting concurrent download without limits.")
|
|
||||||
asyncio.create_task(self._run_download(download))
|
|
||||||
|
|
||||||
async def __limited_concurrent_download(self, download):
|
|
||||||
log.info("Starting limited concurrent download.")
|
|
||||||
async with self.semaphore:
|
async with self.semaphore:
|
||||||
await self._run_download(download)
|
if download.canceled:
|
||||||
|
log.info(f"Download {download.info.title} was canceled, skipping start.")
|
||||||
async def _run_download(self, download):
|
return
|
||||||
if download.canceled:
|
await download.start(self.notifier)
|
||||||
log.info(f"Download {download.info.title} is canceled; skipping start.")
|
self._post_download_cleanup(download)
|
||||||
return
|
|
||||||
await download.start(self.notifier)
|
|
||||||
self._post_download_cleanup(download)
|
|
||||||
|
|
||||||
def _post_download_cleanup(self, download):
|
def _post_download_cleanup(self, download):
|
||||||
if download.info.status != 'finished':
|
if download.info.status != 'finished':
|
||||||
|
|||||||
Reference in New Issue
Block a user