Skip to content

Commit a60c07d

Browse files
authored
Add CONTROL_PLANE_TIMEOUT configuration and apply it across various components (#285)
- Introduced CONTROL_PLANE_TIMEOUT setting in SidecarConfig for controlling request timeouts. - Updated aiohttp ClientSession and AsyncClient to utilize the new timeout configuration. - Modified BlockingRequest to accept a timeout parameter, ensuring consistent timeout handling in blocking requests. - Adjusted RemoteConfigFetcher and EnvApiKeyFetcher to incorporate the timeout setting for improved request management.
1 parent 3984bde commit a60c07d

File tree

6 files changed

+25
-5
lines changed

6 files changed

+25
-5
lines changed

horizon/config.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,12 @@ def __new__(cls, *, prefix=None, is_model=True): # noqa: ARG004
3434
description="URL to the control plane that manages this PDP, typically Permit.io cloud (api.permit.io)",
3535
)
3636

37+
CONTROL_PLANE_TIMEOUT = confi.float(
38+
"CONTROL_PLANE_TIMEOUT",
39+
75,
40+
description="Timeout in seconds for control plane requests",
41+
)
42+
3743
CONTROL_PLANE_PDP_DELTAS_API = confi.str(
3844
"CONTROL_PLANE_PDP_DELTAS_API",
3945
"http://localhost:8000",

horizon/facts/client.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ def client(self) -> AsyncClient:
2626
env_api_key = get_env_api_key()
2727
self._client = AsyncClient(
2828
base_url=sidecar_config.CONTROL_PLANE,
29+
timeout=sidecar_config.CONTROL_PLANE_TIMEOUT,
2930
headers={"Authorization": f"Bearer {env_api_key}"},
3031
trust_env=True,
3132
)

horizon/startup/api_keys.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,11 @@ class EnvApiKeyFetcher:
1919
def __init__(
2020
self,
2121
backend_url: str = sidecar_config.CONTROL_PLANE,
22+
timeout: float = sidecar_config.CONTROL_PLANE_TIMEOUT,
2223
retry_config=None,
2324
):
2425
self._backend_url = backend_url
26+
self._timeout = timeout
2527
self._retry_config = retry_config or DEFAULT_RETRY_CONFIG
2628
self.api_key_level = self._get_api_key_level()
2729

@@ -83,6 +85,7 @@ def _fetch_env_key(self, api_key: str, active_project_key: str, active_env_key:
8385
fetch_with_retry = retry(**self._retry_config)(
8486
lambda: BlockingRequest(
8587
token=api_key,
88+
timeout=self._timeout,
8689
).get(url=api_key_url)
8790
)
8891
try:
@@ -105,6 +108,7 @@ def fetch_scope(self, api_key: str) -> dict | None:
105108
fetch_with_retry = retry(**self._retry_config)(
106109
lambda: BlockingRequest(
107110
token=api_key,
111+
timeout=self._timeout,
108112
).get(url=api_key_url)
109113
)
110114
try:

horizon/startup/blocking_request.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@
66

77

88
class BlockingRequest:
9-
def __init__(self, token: str | None, extra_headers: dict[str, Any] | None = None):
9+
def __init__(self, token: str | None, extra_headers: dict[str, Any] | None = None, timeout: float = 60):
1010
self._token = token
1111
self._extra_headers = {k: v for k, v in (extra_headers or {}).items() if v is not None}
12+
self._timeout = timeout
1213

1314
def _headers(self) -> dict[str, str]:
1415
headers = {}
@@ -22,7 +23,7 @@ def get(self, url: str, params=None) -> dict:
2223
"""
2324
utility method to send a *blocking* HTTP GET request and get the response back.
2425
"""
25-
response = requests.get(url, headers=self._headers(), params=params)
26+
response = requests.get(url, headers=self._headers(), params=params, timeout=self._timeout)
2627

2728
if response.status_code == 401:
2829
raise InvalidPDPTokenError()
@@ -33,7 +34,7 @@ def post(self, url: str, payload: dict | None = None, params=None) -> dict:
3334
"""
3435
utility method to send a *blocking* HTTP POST request with a JSON payload and get the response back.
3536
"""
36-
response = requests.post(url, json=payload, headers=self._headers(), params=params)
37+
response = requests.post(url, json=payload, headers=self._headers(), params=params, timeout=self._timeout)
3738

3839
if response.status_code == 401:
3940
raise InvalidPDPTokenError()

horizon/startup/remote_config.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ def __init__(
5050
backend_url: str = sidecar_config.CONTROL_PLANE,
5151
remote_config_route: str = sidecar_config.REMOTE_CONFIG_ENDPOINT,
5252
shard_id: str | None = sidecar_config.SHARD_ID,
53+
timeout: float = sidecar_config.CONTROL_PLANE_TIMEOUT,
5354
retry_config=None,
5455
):
5556
"""
@@ -63,6 +64,7 @@ def __init__(
6364
self._url = f"{backend_url}{remote_config_route}"
6465
self._backend_url = backend_url
6566
self._token = get_env_api_key()
67+
self._timeout = timeout
6668
self._retry_config = retry_config if retry_config is not None else DEFAULT_RETRY_CONFIG
6769
self._shard_id = shard_id
6870

@@ -91,8 +93,13 @@ def _fetch_config(self) -> RemoteConfig:
9193
However, this is ok because the RemoteConfigFetcher runs *once* when the sidecar starts.
9294
"""
9395
try:
94-
response = BlockingRequest(token=self._token, extra_headers={"X-Shard-ID": self._shard_id}).post(
95-
url=self._url, payload=PersistentStateHandler.build_state_payload_sync()
96+
response = BlockingRequest(
97+
token=self._token,
98+
extra_headers={"X-Shard-ID": self._shard_id},
99+
timeout=self._timeout,
100+
).post(
101+
url=self._url,
102+
payload=PersistentStateHandler.build_state_payload_sync(),
96103
)
97104

98105
try:

horizon/state.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,7 @@ async def _report(self, state: PersistentState | None = None):
200200
config_url = f"{sidecar_config.CONTROL_PLANE}{sidecar_config.REMOTE_STATE_ENDPOINT}"
201201
async with aiohttp.ClientSession(
202202
trust_env=True,
203+
timeout=aiohttp.ClientTimeout(total=sidecar_config.CONTROL_PLANE_TIMEOUT),
203204
) as session:
204205
logger.info("Reporting status update to server...")
205206
response = await session.post(

0 commit comments

Comments
 (0)