diff --git a/CHANGELOG.md b/CHANGELOG.md index f960f840e6..8873f23374 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,14 @@ this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm +## 0.10.8 (2024-09-04) + +### Bug Fixes + +- Avoid raising exception when receiving ReadTimeout on batch upsert entities +- Increased both internal port client and third party client timeout to handle long requests + + ## 0.10.7 (2024-08-28) ### Improvements diff --git a/port_ocean/clients/port/mixins/entities.py b/port_ocean/clients/port/mixins/entities.py index d34d5ce317..f8d5f63fa3 100644 --- a/port_ocean/clients/port/mixins/entities.py +++ b/port_ocean/clients/port/mixins/entities.py @@ -101,7 +101,7 @@ async def batch_upsert_entities( ) for entity in entities ), - return_exceptions=should_raise, + return_exceptions=True, ) entity_results = [ entity for entity in modified_entities_results if isinstance(entity, Entity) diff --git a/port_ocean/clients/port/utils.py b/port_ocean/clients/port/utils.py index 2bbc3359dc..a2c3782c84 100644 --- a/port_ocean/clients/port/utils.py +++ b/port_ocean/clients/port/utils.py @@ -18,7 +18,7 @@ # The max_keepalive_connections can't be too high, as it will cause the application to run out of available connections. PORT_HTTP_MAX_CONNECTIONS_LIMIT = 200 PORT_HTTP_MAX_KEEP_ALIVE_CONNECTIONS = 50 -PORT_HTTP_TIMEOUT = 10.0 +PORT_HTTP_TIMEOUT = 60.0 PORT_HTTPX_TIMEOUT = httpx.Timeout(PORT_HTTP_TIMEOUT) PORT_HTTPX_LIMITS = httpx.Limits( diff --git a/port_ocean/config/settings.py b/port_ocean/config/settings.py index 6a3fd3e7d4..5b9a8e7abb 100644 --- a/port_ocean/config/settings.py +++ b/port_ocean/config/settings.py @@ -67,7 +67,7 @@ class IntegrationConfiguration(BaseOceanSettings, extra=Extra.allow): allow_environment_variables_jq_access: bool = True initialize_port_resources: bool = True scheduled_resync_interval: int | None = None - client_timeout: int = 30 + client_timeout: int = 60 send_raw_data_examples: bool = True port: PortSettings event_listener: EventListenerSettingsType = Field( diff --git a/port_ocean/helpers/retry.py b/port_ocean/helpers/retry.py index 98ecffff34..077c6e0ffb 100644 --- a/port_ocean/helpers/retry.py +++ b/port_ocean/helpers/retry.py @@ -290,6 +290,11 @@ async def _retry_operation_async( if remaining_attempts < 1: self._log_error(request, error) raise + except httpx.ReadTimeout as e: + error = e + if remaining_attempts < 1: + self._log_error(request, error) + raise except httpx.TimeoutException as e: error = e if remaining_attempts < 1: diff --git a/port_ocean/tests/clients/port/mixins/test_entities.py b/port_ocean/tests/clients/port/mixins/test_entities.py new file mode 100644 index 0000000000..0a2d641d1b --- /dev/null +++ b/port_ocean/tests/clients/port/mixins/test_entities.py @@ -0,0 +1,53 @@ +from typing import Any +from unittest.mock import MagicMock + +import pytest + +from port_ocean.clients.port.mixins.entities import EntityClientMixin +from port_ocean.core.models import Entity +from httpx import ReadTimeout + + +errored_entity_identifier: str = "a" +expected_result_entities = [ + Entity(identifier="b", blueprint="b"), + Entity(identifier="c", blueprint="c"), +] +all_entities = [ + Entity(identifier=errored_entity_identifier, blueprint="a") +] + expected_result_entities + + +async def mock_upsert_entity(entity: Entity, *args: Any, **kwargs: Any) -> Entity: + if entity.identifier == errored_entity_identifier: + raise ReadTimeout("") + else: + return entity + + +@pytest.fixture +async def entity_client(monkeypatch: Any) -> EntityClientMixin: + # Arrange + entity_client = EntityClientMixin(auth=MagicMock(), client=MagicMock()) + monkeypatch.setattr(entity_client, "upsert_entity", mock_upsert_entity) + + return entity_client + + +async def test_batch_upsert_entities_read_timeout_should_raise_false( + entity_client: EntityClientMixin, +) -> None: + result_entities = await entity_client.batch_upsert_entities( + entities=all_entities, request_options=MagicMock(), should_raise=False + ) + + assert result_entities == expected_result_entities + + +async def test_batch_upsert_entities_read_timeout_should_raise_true( + entity_client: EntityClientMixin, +) -> None: + with pytest.raises(ReadTimeout): + await entity_client.batch_upsert_entities( + entities=all_entities, request_options=MagicMock(), should_raise=True + ) diff --git a/pyproject.toml b/pyproject.toml index d7060f9561..4ef1caabb7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "port-ocean" -version = "0.10.7" +version = "0.10.8" description = "Port Ocean is a CLI tool for managing your Port projects." readme = "README.md" homepage = "https://app.getport.io"