fix: treat DSM 599 as task-not-ready in _poll_task, poll until 60s timeout
DirSize/MD5 return error 599 while the async task is still initialising on the NAS, not only after the task is gone. Remove the 5-consecutive-599 abort limit and the debug stderr logging; instead pass on 599 and keep polling until the existing 60 s timeout fires. Rename the test that checked the old limit to reflect the new timeout-based behaviour. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
[project]
|
[project]
|
||||||
name = "mcp-synology-filestation"
|
name = "mcp-synology-filestation"
|
||||||
version = "0.2.3"
|
version = "0.2.4"
|
||||||
description = "MCP server for Synology FileStation"
|
description = "MCP server for Synology FileStation"
|
||||||
requires-python = ">=3.12"
|
requires-python = ">=3.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
"""MCP server for Synology FileStation."""
|
"""MCP server for Synology FileStation."""
|
||||||
|
|
||||||
__version__ = "0.2.3"
|
__version__ = "0.2.4"
|
||||||
|
|||||||
@@ -81,26 +81,16 @@ def register_filestation(
|
|||||||
``(True, status_dict)`` on success, or ``(False, "Error: …")`` on
|
``(True, status_dict)`` on success, or ``(False, "Error: …")`` on
|
||||||
DSM error or timeout.
|
DSM error or timeout.
|
||||||
"""
|
"""
|
||||||
import sys as _sys
|
|
||||||
|
|
||||||
from mcp_synology_filestation.client import SynologyError as _SynologyError
|
from mcp_synology_filestation.client import SynologyError as _SynologyError
|
||||||
|
|
||||||
delay = 0.2
|
delay = 0.2
|
||||||
elapsed = initial_delay
|
elapsed = initial_delay
|
||||||
timeout = 60.0
|
timeout = 60.0
|
||||||
consecutive_599 = 0
|
|
||||||
attempt = 0
|
|
||||||
|
|
||||||
_sys.stderr.write(
|
|
||||||
f"[poll] START {api}/status v{version} taskid={taskid} initial_delay={initial_delay}\n"
|
|
||||||
)
|
|
||||||
_sys.stderr.flush()
|
|
||||||
|
|
||||||
if initial_delay > 0:
|
if initial_delay > 0:
|
||||||
await asyncio.sleep(initial_delay)
|
await asyncio.sleep(initial_delay)
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
attempt += 1
|
|
||||||
try:
|
try:
|
||||||
status_data = await client.request(
|
status_data = await client.request(
|
||||||
api,
|
api,
|
||||||
@@ -108,25 +98,12 @@ def register_filestation(
|
|||||||
version=version,
|
version=version,
|
||||||
params={"taskid": taskid},
|
params={"taskid": taskid},
|
||||||
)
|
)
|
||||||
consecutive_599 = 0
|
|
||||||
finished = status_data.get("finished")
|
|
||||||
_sys.stderr.write(
|
|
||||||
f"[poll] #{attempt} elapsed={elapsed:.2f}s finished={finished}"
|
|
||||||
f" data_keys={list(status_data.keys())}\n"
|
|
||||||
)
|
|
||||||
_sys.stderr.flush()
|
|
||||||
except _SynologyError as e:
|
except _SynologyError as e:
|
||||||
_sys.stderr.write(
|
|
||||||
f"[poll] #{attempt} elapsed={elapsed:.2f}s"
|
|
||||||
f" SynologyError code={e.code} msg={e}\n"
|
|
||||||
)
|
|
||||||
_sys.stderr.flush()
|
|
||||||
if e.code == 599:
|
if e.code == 599:
|
||||||
# 599 can be transient (task just started, not yet available).
|
# DSM returns 599 while the async task is still initialising
|
||||||
# Retry up to 5 times before giving up.
|
# or running (task-not-yet-available). Treat it the same as
|
||||||
consecutive_599 += 1
|
# finished=False and keep polling until the 60 s timeout.
|
||||||
if consecutive_599 >= 5:
|
pass
|
||||||
return False, f"Error: {e}"
|
|
||||||
else:
|
else:
|
||||||
return False, f"Error: {e}"
|
return False, f"Error: {e}"
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -1635,8 +1635,8 @@ async def test_dir_size_retries_on_transient_599(config: AppConfig) -> None:
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
async def test_dir_size_fails_after_5_consecutive_599(config: AppConfig) -> None:
|
async def test_dir_size_times_out_on_persistent_599(config: AppConfig) -> None:
|
||||||
"""dir_size gives up and returns Error: after 5 consecutive 599 responses."""
|
"""dir_size returns Error: after 60 s timeout when DSM keeps returning 599."""
|
||||||
client = MagicMock()
|
client = MagicMock()
|
||||||
|
|
||||||
async def _request(api, method, version=None, params=None, **kwargs):
|
async def _request(api, method, version=None, params=None, **kwargs):
|
||||||
@@ -1651,6 +1651,7 @@ async def test_dir_size_fails_after_5_consecutive_599(config: AppConfig) -> None
|
|||||||
result = await tools["dir_size"](path="/dead")
|
result = await tools["dir_size"](path="/dead")
|
||||||
|
|
||||||
assert result.startswith("Error:")
|
assert result.startswith("Error:")
|
||||||
|
assert "timed out" in result.lower() or "60 seconds" in result
|
||||||
|
|
||||||
|
|
||||||
# ──────────────────────────────────────────────────────────────────────────
|
# ──────────────────────────────────────────────────────────────────────────
|
||||||
|
|||||||
@@ -362,7 +362,7 @@ wheels = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mcp-synology-filestation"
|
name = "mcp-synology-filestation"
|
||||||
version = "0.2.0"
|
version = "0.2.4"
|
||||||
source = { editable = "." }
|
source = { editable = "." }
|
||||||
dependencies = [
|
dependencies = [
|
||||||
{ name = "click" },
|
{ name = "click" },
|
||||||
|
|||||||
Reference in New Issue
Block a user