Add configurable Soulseek search timeout and buffer
Introduces 'search_timeout' and 'search_timeout_buffer' options to Soulseek settings in the config, backend, and web UI. The backend now uses these values to control search duration and polling, allowing users to fine-tune how long searches run and how long to wait for late results.
This commit is contained in:
parent
a2bdb93498
commit
5d29131530
4 changed files with 42 additions and 10 deletions
|
|
@ -30,7 +30,9 @@
|
|||
"slskd_url": "http://host.docker.internal:5030",
|
||||
"api_key": "SoulseekAPIKey",
|
||||
"download_path": "/app/downloads",
|
||||
"transfer_path": "/app/Transfer"
|
||||
"transfer_path": "/app/Transfer",
|
||||
"search_timeout": 60,
|
||||
"search_timeout_buffer": 15
|
||||
},
|
||||
"logging": {
|
||||
"path": "logs/app.log",
|
||||
|
|
|
|||
|
|
@ -602,17 +602,22 @@ class SoulseekClient:
|
|||
|
||||
return None
|
||||
|
||||
async def search(self, query: str, timeout: int = 60, progress_callback=None) -> tuple[List[TrackResult], List[AlbumResult]]:
|
||||
async def search(self, query: str, timeout: int = None, progress_callback=None) -> tuple[List[TrackResult], List[AlbumResult]]:
|
||||
if not self.base_url:
|
||||
logger.error("Soulseek client not configured")
|
||||
return [], []
|
||||
|
||||
|
||||
# Get timeout from config if not specified
|
||||
if timeout is None:
|
||||
from config.settings import config_manager
|
||||
timeout = config_manager.get('soulseek.search_timeout', 60)
|
||||
|
||||
# Apply rate limiting before search
|
||||
await self._wait_for_rate_limit()
|
||||
|
||||
|
||||
try:
|
||||
logger.info(f"Starting search for: '{query}'")
|
||||
|
||||
logger.info(f"Starting search for: '{query}' (slskd timeout: {timeout}s)")
|
||||
|
||||
search_data = {
|
||||
'searchText': query,
|
||||
'timeout': timeout * 1000, # slskd expects milliseconds
|
||||
|
|
@ -645,13 +650,24 @@ class SoulseekClient:
|
|||
|
||||
# Track this search as active
|
||||
self.active_searches[search_id] = True
|
||||
|
||||
|
||||
# Get timeout buffer from config
|
||||
from config.settings import config_manager
|
||||
timeout_buffer = config_manager.get('soulseek.search_timeout_buffer', 15)
|
||||
|
||||
# Poll for results - process and emit results immediately when found
|
||||
all_responses = []
|
||||
all_tracks = []
|
||||
all_albums = []
|
||||
poll_interval = 1 # Check every 1.5 seconds for more responsive updates
|
||||
max_polls = int(timeout / poll_interval) # 20 attempts over 30 seconds
|
||||
poll_interval = 1 # Check every 1 second for responsive updates
|
||||
|
||||
# IMPORTANT: Poll for LONGER than slskd searches to catch all results
|
||||
# slskd timeout: how long slskd searches for
|
||||
# polling timeout: how long WE wait for slskd to finish (with buffer)
|
||||
polling_timeout = timeout + timeout_buffer
|
||||
max_polls = int(polling_timeout / poll_interval)
|
||||
|
||||
logger.info(f"Polling for up to {polling_timeout}s (slskd timeout: {timeout}s + buffer: {timeout_buffer}s)")
|
||||
|
||||
for poll_count in range(max_polls):
|
||||
# Check if search was cancelled
|
||||
|
|
|
|||
|
|
@ -2273,6 +2273,16 @@
|
|||
<label>API Key:</label>
|
||||
<input type="password" id="soulseek-api-key" placeholder="Slskd API Key">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Search Timeout (seconds):</label>
|
||||
<input type="number" id="soulseek-search-timeout" placeholder="60" min="15" max="300" value="60">
|
||||
<small style="color: #888; display: block; margin-top: 5px;">How long to search for tracks (15-300 seconds)</small>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Search Timeout Buffer (seconds):</label>
|
||||
<input type="number" id="soulseek-search-timeout-buffer" placeholder="15" min="5" max="60" value="15">
|
||||
<small style="color: #888; display: block; margin-top: 5px;">Extra time to wait for late results (5-60 seconds)</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ListenBrainz Settings -->
|
||||
|
|
|
|||
|
|
@ -1629,6 +1629,8 @@ async function loadSettingsData() {
|
|||
// Populate Soulseek settings
|
||||
document.getElementById('soulseek-url').value = settings.soulseek?.slskd_url || '';
|
||||
document.getElementById('soulseek-api-key').value = settings.soulseek?.api_key || '';
|
||||
document.getElementById('soulseek-search-timeout').value = settings.soulseek?.search_timeout || 60;
|
||||
document.getElementById('soulseek-search-timeout-buffer').value = settings.soulseek?.search_timeout_buffer || 15;
|
||||
|
||||
// Populate ListenBrainz settings
|
||||
document.getElementById('listenbrainz-token').value = settings.listenbrainz?.token || '';
|
||||
|
|
@ -2004,7 +2006,9 @@ async function saveSettings() {
|
|||
slskd_url: document.getElementById('soulseek-url').value,
|
||||
api_key: document.getElementById('soulseek-api-key').value,
|
||||
download_path: document.getElementById('download-path').value,
|
||||
transfer_path: document.getElementById('transfer-path').value
|
||||
transfer_path: document.getElementById('transfer-path').value,
|
||||
search_timeout: parseInt(document.getElementById('soulseek-search-timeout').value) || 60,
|
||||
search_timeout_buffer: parseInt(document.getElementById('soulseek-search-timeout-buffer').value) || 15
|
||||
},
|
||||
listenbrainz: {
|
||||
token: document.getElementById('listenbrainz-token').value
|
||||
|
|
|
|||
Loading…
Reference in a new issue