diff --git a/document-parser/infra/settings.py b/document-parser/infra/settings.py index 496e032..d8f1e48 100644 --- a/document-parser/infra/settings.py +++ b/document-parser/infra/settings.py @@ -46,6 +46,18 @@ class Settings: errors.append( f"default_table_mode must be 'accurate' or 'fast' (got '{self.default_table_mode}')" ) + # Timeout cascade: document_timeout < lock_timeout < conversion_timeout + if self.document_timeout > 0 and self.lock_timeout > 0 and self.conversion_timeout > 0: + if self.document_timeout >= self.lock_timeout: + errors.append( + f"document_timeout ({self.document_timeout}s) must be " + f"< lock_timeout ({self.lock_timeout}s)" + ) + if self.lock_timeout >= self.conversion_timeout: + errors.append( + f"lock_timeout ({self.lock_timeout}s) must be " + f"< conversion_timeout ({self.conversion_timeout}s)" + ) if errors: raise ValueError("Invalid settings:\n " + "\n ".join(errors)) diff --git a/document-parser/tests/test_settings.py b/document-parser/tests/test_settings.py index 9a683fd..604abac 100644 --- a/document-parser/tests/test_settings.py +++ b/document-parser/tests/test_settings.py @@ -79,6 +79,22 @@ class TestSettingsValidation: with pytest.raises(ValueError, match="default_table_mode must be"): Settings(default_table_mode="turbo") + def test_cascade_document_ge_lock_rejected(self): + import pytest + + with pytest.raises(ValueError, match=r"document_timeout.*< lock_timeout"): + Settings(document_timeout=400.0, lock_timeout=300, conversion_timeout=900) + + def test_cascade_lock_ge_conversion_rejected(self): + import pytest + + with pytest.raises(ValueError, match=r"lock_timeout.*< conversion_timeout"): + Settings(document_timeout=100.0, lock_timeout=900, conversion_timeout=900) + + def test_cascade_valid_ordering_accepted(self): + s = Settings(document_timeout=60.0, lock_timeout=300, conversion_timeout=900) + assert s.document_timeout < s.lock_timeout < s.conversion_timeout + def test_multiple_errors_reported(self): import pytest @@ -94,8 +110,9 @@ class TestSettingsFromEnv: monkeypatch.setenv("DEPLOYMENT_MODE", "huggingface") monkeypatch.setenv("DOCLING_SERVE_URL", "http://serve:9000") monkeypatch.setenv("DOCLING_SERVE_API_KEY", "secret-key") - monkeypatch.setenv("CONVERSION_TIMEOUT", "120") + monkeypatch.setenv("CONVERSION_TIMEOUT", "1200") monkeypatch.setenv("DOCUMENT_TIMEOUT", "60.0") + monkeypatch.setenv("LOCK_TIMEOUT", "600") monkeypatch.setenv("MAX_PAGE_COUNT", "20") monkeypatch.setenv("UPLOAD_DIR", "/data/uploads") monkeypatch.setenv("DB_PATH", "/data/test.db") @@ -108,7 +125,8 @@ class TestSettingsFromEnv: assert s.deployment_mode == "huggingface" assert s.docling_serve_url == "http://serve:9000" assert s.docling_serve_api_key == "secret-key" - assert s.conversion_timeout == 120 + assert s.conversion_timeout == 1200 + assert s.lock_timeout == 600 assert s.document_timeout == 60.0 assert s.max_page_count == 20 assert s.upload_dir == "/data/uploads"