Skip to content

feat: pressure non streaming mode - #806

Open
yanksyoon wants to merge 2 commits into
mainfrom
feat/pressure-request-mode
Open

feat: pressure non streaming mode#806
yanksyoon wants to merge 2 commits into
mainfrom
feat/pressure-request-mode

Conversation

@yanksyoon

Copy link
Copy Markdown
Member

What this PR does

Introduce non streaming mode for pressure

Why we need it

Flaky network infrastructure will always fail on pressure stream

Checklist

  • I followed the contributing guide
  • I added or updated the documentation (if applicable)
  • I updated docs/changelog.md with user-relevant changes
  • I used AI to assist with preparing this PR
  • I added or updated tests as needed (unit and integration)
  • If this is a Grafana dashboard: I added a screenshot of the dashboard
  • If this is Terraform: terraform fmt passes and tflint reports no errors
  • If the github-runner-manager application has been changed: The application version number is updated in github-runner-manager/pyproject.toml.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a non-streaming (polling) mode for fetching planner “pressure”, allowing deployments with unreliable streaming connectivity to still scale runner creation based on planner demand.

Changes:

  • Introduces new charm config planner-pressure-mode (stream default, request polling) and validates it in charm state.
  • Plumbs planner_pressure_mode into the generated manager ApplicationConfiguration and into PressureReconcilerConfig.
  • Implements PlannerClient.get_pressure() and updates PressureReconciler create loop to support request-mode polling; updates unit tests and changelog accordingly.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
tests/unit/test_factories.py Asserts planner_pressure_mode is included in generated application config.
tests/unit/test_charm_state.py Adds validation test for invalid mode; asserts valid mode is stored in CharmConfig.
tests/unit/factories.py Sets default planner-pressure-mode in mock charm config.
tests/unit/conftest.py Updates charm state fixture to include planner_pressure_mode.
src/factories.py Plumbs state.charm_config.planner_pressure_mode into ApplicationConfiguration.
src/charm_state.py Adds planner-pressure-mode config name, type, default, and validation/parsing.
github-runner-manager/tests/unit/manager/test_pressure_reconciler.py Updates fake planner for request-mode support and adds request-mode create loop test.
github-runner-manager/src/github_runner_manager/planner_client.py Adds get_pressure() one-shot pressure fetch method.
github-runner-manager/src/github_runner_manager/manager/pressure_reconciler.py Adds planner_pressure_mode to config and implements request-mode polling path in create loop.
github-runner-manager/src/github_runner_manager/configuration/base.py Extends ApplicationConfiguration with planner_pressure_mode.
docs/changelog.md Documents the new config option and reconciler behavior change.
charmcraft.yaml Adds planner-pressure-mode charm config option with default and description.

Comment on lines +89 to +92
data = response.json()
if not isinstance(data, dict) or name not in data:
raise PlannerApiError(f"Unexpected pressure response payload: {data}")

Comment on lines +66 to +80
def get_pressure(self, name: str) -> PressureInfo:
"""Get pressure for the given flavor with a single request.

Args:
name: Flavor name.

Returns:
Parsed pressure info.

Raises:
PlannerConnectionError: On transient connection failures or timeouts.
PlannerApiError: On HTTP errors or invalid payloads.
"""
base = str(self._config.base_url).rstrip("/") + "/"
url = urljoin(base, f"api/v1/flavors/{name}/pressure")
Comment on lines 159 to +162
return
self._handle_create_runners(update.pressure)
self._stop.wait(5)
else:

@yhaliaw yhaliaw left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved with minor changes needed


🤝 Human review with AI assistance.

response = self._session.get(
url,
headers={"Authorization": f"Bearer {self._config.token}"},
timeout=self._config.timeout,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

get_pressure() uses self._config.timeout, whose default is 5 * 60 (300s, line 42) — a value chosen for long-lived streaming connections, not one-shot polls. build_pressure_reconciler constructs PlannerConfiguration without overriding it, so request mode inherits the streaming timeout unchanged.

A slow or hung planner can block the create loop for up to 300 seconds per poll attempt, compounded by the session's urllib3.Retry(total=3, backoff_factor=0.3) on 5xx responses. That makes the effective poll cadence wildly variable under exactly the flaky-network conditions this PR exists to handle, and delays the fallback-to-min_pressure behavior meant to keep runners flowing when the planner is unreachable.

Pass a short explicit timeout for the one-shot request path (a few seconds, consistent with the 5-second poll interval) — either a separate request_timeout field on PlannerConfiguration or an explicit argument at the get_pressure call site.

🤖 AI-assisted

Comment thread tests/unit/factories.py
Comment on lines +34 to 35
PLANNER_PRESSURE_MODE_CONFIG_NAME,
PLANNER_INTEGRATION_NAME,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PLANNER_PRESSURE_MODE_CONFIG_NAME is imported before PLANNER_INTEGRATION_NAME, breaking the alphabetical ordering isort enforces here (every other name in this block is correctly ordered).

The lint tox env runs isort --check-only --diff, so this will fail CI lint as-is.

Suggested change
PLANNER_PRESSURE_MODE_CONFIG_NAME,
PLANNER_INTEGRATION_NAME,
PLANNER_INTEGRATION_NAME,
PLANNER_PRESSURE_MODE_CONFIG_NAME,

🤖 AI-assisted

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants