Skip to content

Commit fe6ed06

Browse files
authored
Add niceness configuration for process priority control (#264)
Introduce the `HORIZON_NICENESS` configuration to control the process niceness value, enabling better CPU resource allocation. Implemented `set_process_niceness` to adjust the process priority based on the specified value, with safety checks and logging for status and errors. This ensures processes can be fine-tuned for performance or background execution as needed.
1 parent 7d3a11d commit fe6ed06

File tree

2 files changed

+45
-0
lines changed

2 files changed

+45
-0
lines changed

horizon/config.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,16 @@ def parse_plugins(value: Any) -> dict[str, dict[str, int | bool | str]]:
265265
description="The path to the file that contains the PDP version",
266266
)
267267

268+
HORIZON_NICENESS = confi.int(
269+
"HORIZON_NICENESS",
270+
10,
271+
description=(
272+
"The niceness value for the PDP Horizon process (Python process). "
273+
"Niceness values range from -20 (highest priority) to 19 (lowest priority) with 0 is neutral. "
274+
"Adjusting this can help manage CPU resource allocation. "
275+
),
276+
)
277+
268278
@staticmethod
269279
def parse_callbacks(value: Any) -> list[CallbackEntry]:
270280
if isinstance(value, str):

horizon/pdp.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import logging
2+
import os
23
import sys
34
from pathlib import Path
45
from uuid import UUID, uuid4
@@ -45,6 +46,37 @@
4546
OPA_LOGGER_MODULE = "opal_client.opa.logger"
4647

4748

49+
def set_process_niceness(target_nice: int) -> None:
50+
"""
51+
Attempts to set the current process's niceness value to `target_nice`.
52+
This operation is performed only once during the call.
53+
54+
This function is idempotent if the current niceness already equals `target_nice`.
55+
Setting a lower niceness value (increasing priority) may require CAP_SYS_NICE
56+
capabilities and could fail if the process lacks sufficient privileges.
57+
"""
58+
if target_nice < -20 or target_nice > 19:
59+
raise ValueError(f"Target niceness must be between -20 and 19, got {target_nice}")
60+
61+
try:
62+
current_niceness = os.nice(0) # Read current niceness without changing it
63+
delta = target_nice - current_niceness
64+
if delta != 0:
65+
os.nice(delta) # Apply the change
66+
new_niceness = os.nice(0) # Read the new niceness to confirm
67+
logging.info(
68+
"Changed the process niceness by %d from %d to %d (target was %d).",
69+
delta,
70+
current_niceness,
71+
new_niceness,
72+
target_nice,
73+
)
74+
else:
75+
logging.debug("Process niceness is already %d, which matches the target; no change made.", current_niceness)
76+
except OSError as exc:
77+
logging.warning("Failed to change process niceness to %d: %s", target_nice, exc)
78+
79+
4880
def apply_config(overrides_dict: dict, config_object: Confi):
4981
"""
5082
apply config values from dict into a confi object
@@ -131,6 +163,9 @@ def __init__(self):
131163
if sidecar_config.ENABLE_MONITORING:
132164
self._configure_monitoring()
133165

166+
if sidecar_config.HORIZON_NICENESS:
167+
set_process_niceness(sidecar_config.HORIZON_NICENESS)
168+
134169
self._opal = OpalClient(shard_id=sidecar_config.SHARD_ID, data_topics=self._fix_data_topics())
135170
self._inject_extra_callbacks()
136171
# remove default data update callbacks that are not needed and might be managed by the control plane

0 commit comments

Comments
 (0)