Skip to content

Commit ab1b54a

Browse files
shalev007Shalev Avhar
andauthored
[Core] Support the reduction of Port rate limit in the integrations (#1155)
# Description What - I updated the retry mechanism to ensure the total retry time is capped at 5 minutes, with a maximum backoff time of 5 minutes between retries. Why - This change is needed to handle the reduced port rate limit in integrations more effectively, minimizing the risk of overwhelming the system while still ensuring retries are reasonable. How - I adjusted the retry logic to distribute retries over the 5-minute window, scaling backoff times to align with the reduced rate limit without exceeding the time limit. ## Type of change Please leave one option from the following and delete the rest: - [ ] Bug fix (non-breaking change which fixes an issue) - [ ] New feature (non-breaking change which adds functionality) - [ ] New Integration (non-breaking change which adds a new integration) - [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) - [X] Non-breaking change (fix of existing functionality that will not change current behavior) - [ ] Documentation (added/updated documentation) <h4> All tests should be run against the port production environment(using a testing org). </h4> ### Core testing checklist - [ ] Integration able to create all default resources from scratch - [ ] Resync finishes successfully - [ ] Resync able to create entities - [ ] Resync able to update entities - [ ] Resync able to detect and delete entities - [ ] Scheduled resync able to abort existing resync and start a new one - [ ] Tested with at least 2 integrations from scratch - [ ] Tested with Kafka and Polling event listeners - [ ] Tested deletion of entities that don't pass the selector ### Integration testing checklist - [ ] Integration able to create all default resources from scratch - [ ] Resync able to create entities - [ ] Resync able to update entities - [ ] Resync able to detect and delete entities - [ ] Resync finishes successfully - [ ] If new resource kind is added or updated in the integration, add example raw data, mapping and expected result to the `examples` folder in the integration directory. - [ ] If resource kind is updated, run the integration with the example data and check if the expected result is achieved - [ ] If new resource kind is added or updated, validate that live-events for that resource are working as expected - [ ] Docs PR link [here](#) ### Preflight checklist - [ ] Handled rate limiting - [ ] Handled pagination - [ ] Implemented the code in async - [ ] Support Multi account ## Screenshots Include screenshots from your environment showing how the resources of the integration will look. ## API Documentation Provide links to the API documentation used for this integration. --------- Co-authored-by: Shalev Avhar <shalev@getport.io>
1 parent a0ef85e commit ab1b54a

File tree

2 files changed

+14
-8
lines changed

2 files changed

+14
-8
lines changed

port_ocean/clients/port/utils.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
# period of time, before raising an exception.
1717
# The max_connections value can't be too high, as it will cause the application to run out of memory.
1818
# The max_keepalive_connections can't be too high, as it will cause the application to run out of available connections.
19-
PORT_HTTP_MAX_CONNECTIONS_LIMIT = 200
19+
PORT_HTTP_MAX_CONNECTIONS_LIMIT = 100
2020
PORT_HTTP_MAX_KEEP_ALIVE_CONNECTIONS = 50
2121
PORT_HTTP_TIMEOUT = 60.0
2222

@@ -28,13 +28,19 @@
2828

2929
_http_client: LocalStack[httpx.AsyncClient] = LocalStack()
3030

31+
FIVE_MINUETS = 60 * 5
32+
3133

3234
def _get_http_client_context(port_client: "PortClient") -> httpx.AsyncClient:
3335
client = _http_client.top
3436
if client is None:
3537
client = OceanAsyncClient(
3638
TokenRetryTransport,
37-
transport_kwargs={"port_client": port_client},
39+
transport_kwargs={
40+
"port_client": port_client,
41+
"max_backoff_wait": FIVE_MINUETS,
42+
"base_delay": 0.3,
43+
},
3844
timeout=PORT_HTTPX_TIMEOUT,
3945
limits=PORT_HTTPX_LIMITS,
4046
)

port_ocean/helpers/retry.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -55,14 +55,14 @@ class RetryTransport(httpx.AsyncBaseTransport, httpx.BaseTransport):
5555
HTTPStatus.GATEWAY_TIMEOUT,
5656
]
5757
)
58-
MAX_BACKOFF_WAIT = 60
58+
MAX_BACKOFF_WAIT_IN_SECONDS = 60
5959

6060
def __init__(
6161
self,
6262
wrapped_transport: Union[httpx.BaseTransport, httpx.AsyncBaseTransport],
6363
max_attempts: int = 10,
64-
max_backoff_wait: float = MAX_BACKOFF_WAIT,
65-
backoff_factor: float = 0.1,
64+
max_backoff_wait: float = MAX_BACKOFF_WAIT_IN_SECONDS,
65+
base_delay: float = 0.1,
6666
jitter_ratio: float = 0.1,
6767
respect_retry_after_header: bool = True,
6868
retryable_methods: Iterable[str] | None = None,
@@ -81,7 +81,7 @@ def __init__(
8181
max_backoff_wait (float, optional):
8282
The maximum amount of time (in seconds) to wait before retrying a request.
8383
Defaults to 60.
84-
backoff_factor (float, optional):
84+
base_delay (float, optional):
8585
The factor by which the waiting time will be multiplied in each retry attempt.
8686
Defaults to 0.1.
8787
jitter_ratio (float, optional):
@@ -105,7 +105,7 @@ def __init__(
105105
)
106106

107107
self._max_attempts = max_attempts
108-
self._backoff_factor = backoff_factor
108+
self._base_delay = base_delay
109109
self._respect_retry_after_header = respect_retry_after_header
110110
self._retryable_methods = (
111111
frozenset(retryable_methods)
@@ -255,7 +255,7 @@ def _calculate_sleep(
255255
except ValueError:
256256
pass
257257

258-
backoff = self._backoff_factor * (2 ** (attempts_made - 1))
258+
backoff = self._base_delay * (2 ** (attempts_made - 1))
259259
jitter = (backoff * self._jitter_ratio) * random.choice([1, -1])
260260
total_backoff = backoff + jitter
261261
return min(total_backoff, self._max_backoff_wait)

0 commit comments

Comments
 (0)