Skip to content
This repository was archived by the owner on Jan 23, 2026. It is now read-only.

acquisition timeout support and humanized durations#740

Merged
mangelajo merged 1 commit intomainfrom
acquisition-timeout
Nov 19, 2025
Merged

acquisition timeout support and humanized durations#740
mangelajo merged 1 commit intomainfrom
acquisition-timeout

Conversation

@mangelajo
Copy link
Copy Markdown
Member

@mangelajo mangelajo commented Nov 7, 2025

now all this is possible:

➜  jmp shell -l board-type=renesas-rcar-s4 --acquisition-timeout 1h

[11/07/2025 17:27:25] INFO     INFO:jumpstarter.client.lease:Acquiring lease 019a5f24-e84c-7821-a516-c5fdd0b6f065 for selector                    lease.py:73
                               board-type=renesas-rcar-s4 for duration 0:30:00                                                                               


➜  jmp shell -l board-type=renesas-rcar-s4 --acquisition-timeout 1h --duration 1h30m 

[11/07/2025 17:27:39] INFO     INFO:jumpstarter.client.lease:Acquiring lease 019a5f25-1d8f-7dea-a5ef-05833059d515 for selector                    lease.py:73
                               board-type=renesas-rcar-s4 for duration 1:30:00                                                                               


➜  jmp shell -l board-type=renesas-rcar-s4 --acquisition-timeout 01:00:00 --duration 01:30:00 

[11/07/2025 17:28:00] INFO     INFO:jumpstarter.client.lease:Acquiring lease 019a5f25-6fad-72ad-b2b4-0baec45e813d for selector                    lease.py:73
                               board-type=renesas-rcar-s4 for duration 1:30:00                                                                               


➜  jmp shell -l board-type=renesas-rcar-s4 --acquisition-timeout 01:00 --duration 01:30   

[11/07/2025 17:28:10] INFO     INFO:jumpstarter.client.lease:Acquiring lease 019a5f25-989d-7891-b977-941110f2d8dc for selector                    lease.py:73
                               board-type=renesas-rcar-s4 for duration 0:01:30                                                                               

Summary by CodeRabbit

  • New Features

    • Accept durations as timedeltas, plain numbers, or human-readable/ISO8601 strings.
    • Added --acquisition-timeout option to configure lease acquisition timeout (enforced 5s minimum).
  • Bug Fixes

    • Clearer validation and error messages for invalid or too-small duration inputs.
  • Documentation

    • Updated help text to list supported duration formats and minimum timeout guidance.

@netlify
Copy link
Copy Markdown

netlify Bot commented Nov 7, 2025

Deploy Preview for jumpstarter-docs ready!

Name Link
🔨 Latest commit 2461a69
🔍 Latest deploy log https://app.netlify.com/projects/jumpstarter-docs/deploys/691dcfd00aa17300093a2699
😎 Deploy Preview https://deploy-preview-740--jumpstarter-docs.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Nov 7, 2025

Walkthrough

Adds an acquisition-timeout end-to-end: enhanced duration parsing with minimum enforcement, a new CLI option --acquisition-timeout, wiring through the shell command, and propagation into ClientConfigV1Alpha1.lease_async as an acquisition timeout (seconds).

Changes

Cohort / File(s) Summary
CLI duration parsing & option
packages/jumpstarter-cli/jumpstarter_cli/common.py
DurationParamType gained `init(minimum: timedelta
Shell command wiring
packages/jumpstarter-cli/jumpstarter_cli/shell.py
Imported opt_acquisition_timeout; extended _shell_with_signal_handling(...) and shell(...) signatures to accept acquisition_timeout; added @opt_acquisition_timeout() decorator on shell and forwards acquisition_timeout into config.lease_async(...).
Client lease API
packages/jumpstarter/jumpstarter/config/client.py
ClientConfigV1Alpha1.lease_async signature adds `acquisition_timeout: timedelta
Dependencies
packages/jumpstarter-cli/pyproject.toml
Added runtime dependency pytimeparse2>=1.7.1.

Sequence Diagram(s)

sequenceDiagram
    participant CLI as CLI (shell)
    participant Parser as DurationParamType
    participant Handler as _shell_with_signal_handling
    participant Config as ClientConfigV1Alpha1
    participant Lease as Lease

    CLI->>Parser: parse --acquisition-timeout value
    Parser-->>CLI: returns timedelta (enforces minimum 5s)
    CLI->>Handler: shell(..., acquisition_timeout=td)
    activate Handler
    Handler->>Config: lease_async(..., acquisition_timeout=td)
    activate Config
    Config->>Config: compute acquisition_timeout_seconds\n(arg or config default)
    Config->>Lease: new Lease(..., acquisition_timeout_seconds)
    Lease-->>Config: Lease instance
    Config-->>Handler: lease result
    deactivate Handler
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Pay extra attention to:
    • DurationParamType.convert() parsing order, fallback paths, and error messages.
    • All call sites and decorators in shell.py to ensure the new parameter is correctly threaded.
    • ClientConfigV1Alpha1.lease_async conversion to seconds and type consistency passed to Lease.

Possibly related PRs

Poem

🐰 I parse the seconds, soft and bright,
Five beats bound before the fight.
Strings to moments, tidy and clean,
A hopping option: acquisition-timeout seen. 🥕

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main changes: it adds acquisition timeout support and introduces humanized duration parsing capabilities.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch acquisition-timeout

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9393bda and 2461a69.

⛔ Files ignored due to path filters (1)
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (4)
  • packages/jumpstarter-cli/jumpstarter_cli/common.py (4 hunks)
  • packages/jumpstarter-cli/jumpstarter_cli/shell.py (5 hunks)
  • packages/jumpstarter-cli/pyproject.toml (1 hunks)
  • packages/jumpstarter/jumpstarter/config/client.py (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/jumpstarter-cli/pyproject.toml
  • packages/jumpstarter/jumpstarter/config/client.py
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: mangelajo
Repo: jumpstarter-dev/jumpstarter PR: 610
File: packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/client.py:488-491
Timestamp: 2025-09-15T08:18:48.571Z
Learning: In the jumpstarter project, code review suggestions should stay focused on the specific scope of the PR. Suggestions about general improvements like timeout handling or error handling that are unrelated to the core changes being made should be avoided, even if they apply to modified code lines.
📚 Learning: 2025-09-15T08:18:48.571Z
Learnt from: mangelajo
Repo: jumpstarter-dev/jumpstarter PR: 610
File: packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/client.py:488-491
Timestamp: 2025-09-15T08:18:48.571Z
Learning: In the jumpstarter project, code review suggestions should stay focused on the specific scope of the PR. Suggestions about general improvements like timeout handling or error handling that are unrelated to the core changes being made should be avoided, even if they apply to modified code lines.

Applied to files:

  • packages/jumpstarter-cli/jumpstarter_cli/common.py
🧬 Code graph analysis (1)
packages/jumpstarter-cli/jumpstarter_cli/shell.py (1)
packages/jumpstarter/jumpstarter/config/client.py (2)
  • lease_async (252-296)
  • lease (135-143)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
  • GitHub Check: Redirect rules - jumpstarter-docs
  • GitHub Check: Header rules - jumpstarter-docs
  • GitHub Check: Pages changed - jumpstarter-docs
  • GitHub Check: e2e
  • GitHub Check: pytest-matrix (macos-15, 3.11)
  • GitHub Check: pytest-matrix (ubuntu-24.04, 3.12)
  • GitHub Check: pytest-matrix (ubuntu-24.04, 3.13)
  • GitHub Check: pytest-matrix (macos-15, 3.13)
  • GitHub Check: pytest-matrix (ubuntu-24.04, 3.11)
  • GitHub Check: build
🔇 Additional comments (8)
packages/jumpstarter-cli/jumpstarter_cli/common.py (4)

6-6: LGTM!

The import is properly used in the enhanced duration parsing logic.


19-21: LGTM!

The minimum parameter enables flexible duration validation. The implementation is clean and correctly stores the constraint for enforcement in convert.


23-71: LGTM!

The multi-stage parsing strategy is well-designed:

  • Maintains backward compatibility by trying plain integers first
  • Leverages pytimeparse2 for human-readable formats before falling back to pydantic for ISO 8601
  • Minimum validation correctly enforces the constraint with clear error messaging
  • Error messages provide helpful examples of accepted formats

116-128: LGTM!

The acquisition timeout definitions are well-structured:

  • The 5-second minimum aligns with the help text constraint
  • The option properly uses the validating type
  • Default None allows fallback to configuration defaults when not specified
packages/jumpstarter-cli/jumpstarter_cli/shell.py (4)

11-11: LGTM!

The import is correctly used as a decorator on the shell command.


36-48: LGTM!

The parameter is correctly threaded through to config.lease_async, matching its signature. The downstream conversion to seconds (in client.py) aligns with the Lease constructor's expectations.


75-78: LGTM!

The decorator and parameter addition follow the established pattern used by other CLI options in this command.


93-102: LGTM!

The acquisition_timeout is correctly passed through the async shell invocation. The parameter is appropriately scoped to the ClientConfigV1Alpha1 case, as ExporterConfigV1Alpha1 uses local exporters that don't require lease acquisition.

Tip

📝 Customizable high-level summaries are now available in beta!

You can now customize how CodeRabbit generates the high-level summary in your pull requests — including its content, structure, tone, and formatting.

  • Provide your own instructions using the high_level_summary_instructions setting.
  • Format the summary however you like (bullet lists, tables, multi-section layouts, contributor stats, etc.).
  • Use high_level_summary_in_walkthrough to move the summary from the description to the walkthrough section.

Example instruction:

"Divide the high-level summary into five sections:

  1. 📝 Description — Summarize the main change in 50–60 words, explaining what was done.
  2. 📓 References — List relevant issues, discussions, documentation, or related PRs.
  3. 📦 Dependencies & Requirements — Mention any new/updated dependencies, environment variable changes, or configuration updates.
  4. 📊 Contributor Summary — Include a Markdown table showing contributions:
    | Contributor | Lines Added | Lines Removed | Files Changed |
  5. ✔️ Additional Notes — Add any extra reviewer context.
    Keep each section concise (under 200 words) and use bullet or numbered lists for clarity."

Note: This feature is currently in beta for Pro-tier users, and pricing will be announced later.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (2)
packages/jumpstarter-cli/jumpstarter_cli/shell.py (1)

36-38: Consider adding type annotations to function parameters.

For consistency with the rest of the codebase and improved IDE support, consider adding type hints to all parameters in _shell_with_signal_handling.

Apply this diff to add type annotations:

 async def _shell_with_signal_handling(
-    config, selector, lease_name, duration, exporter_logs, command, acquisition_timeout
+    config: ClientConfigV1Alpha1,
+    selector: str,
+    lease_name: str | None,
+    duration: timedelta,
+    exporter_logs: bool,
+    command: tuple[str, ...],
+    acquisition_timeout: timedelta | None,
 ):
packages/jumpstarter/jumpstarter/config/client.py (1)

267-272: Consider adding inline documentation for the new parameter.

Adding a docstring or inline comment explaining the acquisition_timeout behavior would help future maintainers understand the fallback logic.

Example addition above the method:

@asynccontextmanager
async def lease_async(
    self,
    selector: str,
    lease_name: str | None,
    duration: timedelta,
    portal: BlockingPortal,
    acquisition_timeout: timedelta | None = None,
):
    """
    Acquire a lease asynchronously.
    
    Args:
        acquisition_timeout: Optional timeout for lease acquisition. 
            If None, uses the configured default from self.leases.acquisition_timeout.
    """
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 72b3efa and 74ad53d.

⛔ Files ignored due to path filters (1)
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (4)
  • packages/jumpstarter-cli/jumpstarter_cli/common.py (4 hunks)
  • packages/jumpstarter-cli/jumpstarter_cli/shell.py (5 hunks)
  • packages/jumpstarter-cli/pyproject.toml (1 hunks)
  • packages/jumpstarter/jumpstarter/config/client.py (3 hunks)
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-10-14T17:43:07.788Z
Learnt from: michalskrivanek
Repo: jumpstarter-dev/jumpstarter PR: 704
File: packages/jumpstarter/jumpstarter/client/grpc.py:100-107
Timestamp: 2025-10-14T17:43:07.788Z
Learning: In the Jumpstarter client lease model (packages/jumpstarter/jumpstarter/client/grpc.py), `effective_duration` represents the elapsed time for an active lease so far, not the total duration. To calculate expected release time, use `effective_begin_time + duration` (where `duration` is the configured/requested duration), not `effective_begin_time + effective_duration`.

Applied to files:

  • packages/jumpstarter/jumpstarter/config/client.py
📚 Learning: 2025-11-05T13:45:58.271Z
Learnt from: mangelajo
Repo: jumpstarter-dev/jumpstarter PR: 735
File: packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/client.py:15-15
Timestamp: 2025-11-05T13:45:58.271Z
Learning: In packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/client.py, pexpect is intentionally used as a transitive dependency through the jumpstarter-driver-pyserial package. The flashers package does not declare pexpect as a direct dependency because the pyserial driver package is intended to control the pexpect version.

Applied to files:

  • packages/jumpstarter-cli/pyproject.toml
🧬 Code graph analysis (1)
packages/jumpstarter-cli/jumpstarter_cli/shell.py (3)
packages/jumpstarter/jumpstarter/config/client.py (2)
  • lease_async (252-296)
  • lease (135-143)
packages/jumpstarter-cli-common/jumpstarter_cli_common/exceptions.py (1)
  • handle_exceptions_with_reauthentication (89-106)
packages/jumpstarter-cli/jumpstarter_cli/login.py (1)
  • relogin_client (141-155)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
  • GitHub Check: Redirect rules - jumpstarter-docs
  • GitHub Check: Header rules - jumpstarter-docs
  • GitHub Check: Pages changed - jumpstarter-docs
  • GitHub Check: build
  • GitHub Check: pytest-matrix (macos-15, 3.11)
  • GitHub Check: pytest-matrix (macos-15, 3.12)
  • GitHub Check: pytest-matrix (ubuntu-24.04, 3.11)
  • GitHub Check: pytest-matrix (macos-15, 3.13)
  • GitHub Check: pytest-matrix (ubuntu-24.04, 3.12)
  • GitHub Check: e2e
🔇 Additional comments (5)
packages/jumpstarter-cli/pyproject.toml (1)

16-16: LGTM!

The pytimeparse2 dependency addition properly supports the new human-readable duration parsing feature introduced in the CLI.

packages/jumpstarter-cli/jumpstarter_cli/shell.py (1)

36-38: LGTM!

The acquisition_timeout parameter is correctly threaded through to the lease acquisition flow.

Also applies to: 48-48

packages/jumpstarter/jumpstarter/config/client.py (1)

258-258: LGTM!

The acquisition_timeout parameter is correctly added with proper type hints, and the conversion logic appropriately falls back to the configured default when not specified.

Also applies to: 267-272, 285-285

packages/jumpstarter-cli/jumpstarter_cli/common.py (2)

19-21: LGTM!

The enhanced duration parsing implementation is robust with multiple input formats (timedelta, int, string), clear error messages, and proper minimum validation. Backward compatibility is maintained.

Also applies to: 23-65


108-120: LGTM!

The acquisition timeout option is properly configured with a sensible 5-second minimum and clear help text.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 74ad53d and fd581e2.

📒 Files selected for processing (1)
  • packages/jumpstarter-cli/jumpstarter_cli/common.py (4 hunks)
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: mangelajo
Repo: jumpstarter-dev/jumpstarter PR: 610
File: packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/client.py:488-491
Timestamp: 2025-09-15T08:18:48.571Z
Learning: In the jumpstarter project, code review suggestions should stay focused on the specific scope of the PR. Suggestions about general improvements like timeout handling or error handling that are unrelated to the core changes being made should be avoided, even if they apply to modified code lines.
🪛 GitHub Actions: Lint
packages/jumpstarter-cli/jumpstarter_cli/common.py

[error] 50-50: ruff check failed with E501: Line too long (128 > 120) on line 50. Command: ruff check /home/runner/work/jumpstarter/jumpstarter

🪛 GitHub Check: ruff
packages/jumpstarter-cli/jumpstarter_cli/common.py

[failure] 50-50: Ruff (E501)
packages/jumpstarter-cli/jumpstarter_cli/common.py:50:121: E501 Line too long (128 > 120)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
  • GitHub Check: Redirect rules - jumpstarter-docs
  • GitHub Check: Header rules - jumpstarter-docs
  • GitHub Check: Pages changed - jumpstarter-docs
  • GitHub Check: pytest-matrix (macos-15, 3.11)
  • GitHub Check: pytest-matrix (macos-15, 3.13)
  • GitHub Check: pytest-matrix (ubuntu-24.04, 3.12)
  • GitHub Check: pytest-matrix (macos-15, 3.12)
  • GitHub Check: e2e
  • GitHub Check: pytest-matrix (ubuntu-24.04, 3.13)
  • GitHub Check: pytest-matrix (ubuntu-24.04, 3.11)
🔇 Additional comments (5)
packages/jumpstarter-cli/jumpstarter_cli/common.py (5)

6-6: LGTM: pytimeparse2 integration.

The import enables human-readable duration parsing as described in the PR objectives.


19-21: LGTM: Minimum duration support.

The addition of a configurable minimum parameter enables validation for use cases like acquisition timeout where a floor is required.


23-28: LGTM: Backward-compatible handling of timedelta and int.

Preserving int-as-seconds maintains compatibility while the new code variable enables downstream minimum validation.


54-68: LGTM: Type validation and minimum enforcement.

The minimum check (lines 61-66) correctly enforces the floor when specified, and the error message clearly communicates the requirement in seconds.


78-87: LGTM: Documentation and acquisition timeout option.

The updated help text clearly describes supported formats with examples, and the new ACQUISITION_TIMEOUT constant with a 5-second minimum is appropriate for preventing overly aggressive timeout values.

Also applies to: 113-125

Comment thread packages/jumpstarter-cli/jumpstarter_cli/common.py
@mangelajo mangelajo force-pushed the acquisition-timeout branch from fd581e2 to ced145a Compare November 7, 2025 16:52
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
packages/jumpstarter/jumpstarter/config/client.py (1)

134-143: Consider adding acquisition_timeout to synchronous API for consistency.

The synchronous lease() method doesn't expose the acquisition_timeout parameter, creating an API inconsistency with lease_async(). Users calling the synchronous wrapper cannot override the timeout per call.

If desired, apply this diff to add the parameter:

 def lease(
     self,
     selector: str | None = None,
     lease_name: str | None = None,
     duration: timedelta = timedelta(minutes=30),
+    acquisition_timeout: timedelta | None = None,
 ):
     with start_blocking_portal() as portal:
-        with portal.wrap_async_context_manager(self.lease_async(selector, lease_name, duration, portal)) as lease:
+        with portal.wrap_async_context_manager(
+            self.lease_async(selector, lease_name, duration, portal, acquisition_timeout)
+        ) as lease:
             yield lease
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fd581e2 and ced145a.

⛔ Files ignored due to path filters (1)
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (4)
  • packages/jumpstarter-cli/jumpstarter_cli/common.py (4 hunks)
  • packages/jumpstarter-cli/jumpstarter_cli/shell.py (5 hunks)
  • packages/jumpstarter-cli/pyproject.toml (1 hunks)
  • packages/jumpstarter/jumpstarter/config/client.py (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/jumpstarter-cli/pyproject.toml
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: mangelajo
Repo: jumpstarter-dev/jumpstarter PR: 610
File: packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/client.py:488-491
Timestamp: 2025-09-15T08:18:48.571Z
Learning: In the jumpstarter project, code review suggestions should stay focused on the specific scope of the PR. Suggestions about general improvements like timeout handling or error handling that are unrelated to the core changes being made should be avoided, even if they apply to modified code lines.
📚 Learning: 2025-10-14T17:43:07.788Z
Learnt from: michalskrivanek
Repo: jumpstarter-dev/jumpstarter PR: 704
File: packages/jumpstarter/jumpstarter/client/grpc.py:100-107
Timestamp: 2025-10-14T17:43:07.788Z
Learning: In the Jumpstarter client lease model (packages/jumpstarter/jumpstarter/client/grpc.py), `effective_duration` represents the elapsed time for an active lease so far, not the total duration. To calculate expected release time, use `effective_begin_time + duration` (where `duration` is the configured/requested duration), not `effective_begin_time + effective_duration`.

Applied to files:

  • packages/jumpstarter/jumpstarter/config/client.py
🧬 Code graph analysis (1)
packages/jumpstarter-cli/jumpstarter_cli/shell.py (1)
packages/jumpstarter/jumpstarter/config/client.py (2)
  • lease_async (252-296)
  • lease (135-143)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
  • GitHub Check: Redirect rules - jumpstarter-docs
  • GitHub Check: Header rules - jumpstarter-docs
  • GitHub Check: Pages changed - jumpstarter-docs
  • GitHub Check: e2e
  • GitHub Check: build
  • GitHub Check: pytest-matrix (ubuntu-24.04, 3.11)
  • GitHub Check: pytest-matrix (macos-15, 3.11)
  • GitHub Check: pytest-matrix (macos-15, 3.13)
  • GitHub Check: pytest-matrix (ubuntu-24.04, 3.12)
  • GitHub Check: pytest-matrix (ubuntu-24.04, 3.13)
🔇 Additional comments (10)
packages/jumpstarter/jumpstarter/config/client.py (2)

89-96: LGTM! Configuration looks solid.

The ClientConfigV1Alpha1Lease class properly defines the acquisition timeout with sensible defaults (2 hours) and minimum constraints (5 seconds) that align with the CLI validation.


258-258: LGTM! Acquisition timeout wiring is correct.

The parameter addition and conversion logic properly handles the timedelta-to-seconds conversion and falls back to the config default when not specified.

Also applies to: 267-272, 285-285

packages/jumpstarter-cli/jumpstarter_cli/shell.py (2)

11-11: LGTM! Import and signature update are correct.

The acquisition timeout parameter is properly imported and added to the function signature.

Also applies to: 36-38


48-48: LGTM! Parameter wiring is complete and correct.

The acquisition timeout flows properly from the CLI decorator through the call chain to the lease context.

Also applies to: 75-75, 78-78, 94-101

packages/jumpstarter-cli/jumpstarter_cli/common.py (6)

6-6: LGTM! Import is correct.

The pytimeparse2 import enables human-readable duration parsing.


19-21: LGTM! Minimum parameter addition is clean.

The __init__ method properly stores the optional minimum constraint.


23-63: LGTM! Three-tier parsing logic is sound.

The parsing strategy maintains backward compatibility (int strings) while adding human-readable format support (pytimeparse2) and ISO 8601 fallback (pydantic). The line-length issue from the previous review has been resolved by splitting the error message.


64-71: LGTM! Minimum validation is correct.

The validation properly checks against the minimum constraint and provides a clear error message.


85-90: LGTM! Help text is clear and comprehensive.

The updated documentation clearly describes all supported duration formats with examples and a reference to the pytimeparse2 documentation.


116-128: LGTM! Acquisition timeout option is properly configured.

The ACQUISITION_TIMEOUT type with a 5-second minimum aligns with the configuration validation in client.py, and the CLI option is clearly documented.

@mangelajo mangelajo changed the title acquisition timeout support and humanized duration reading acquisition timeout support and humanized duratios Nov 7, 2025
@mangelajo mangelajo changed the title acquisition timeout support and humanized duratios acquisition timeout support and humanized durations Nov 7, 2025
@bennyz
Copy link
Copy Markdown
Member

bennyz commented Nov 9, 2025

i feel like --acquisition-timeout pollutes the options a little, jmp shell is usually used by end users for ad-hoc work, i don't think they actually wait in most cases, and for the jmp create lease there's plenty of options for the caller to decide how to timeout

@mangelajo
Copy link
Copy Markdown
Member Author

I think it’s helpful to let us specify dynamically from a task. :-)

@mangelajo
Copy link
Copy Markdown
Member Author

I think it’s helpful to let us specify dynamically from a task. :-)

I will split the humanized duration and the new flag, what do you think of a flag for create lease, one for waiting and another one to specify the max wait?

@mangelajo
Copy link
Copy Markdown
Member Author

i feel like --acquisition-timeout pollutes the options a little, jmp shell is usually used by end users for ad-hoc work, i don't think they actually wait in most cases, and for the jmp create lease there's plenty of options for the caller to decide how to timeout

I found a use case today where I missed it...
I was trying to do a

for x in 01 02 03 04 05; do jmp shell -l device=qride-$x --acquisition-timeout 30s ./qcom-info.py; done

@mangelajo
Copy link
Copy Markdown
Member Author

Thank you benny

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
packages/jumpstarter/jumpstarter/config/client.py (1)

135-143: Consider extending the synchronous lease() method for API consistency.

The synchronous lease() method doesn't accept an acquisition_timeout parameter, so callers using this wrapper will always use the configured default. For API consistency, consider adding the parameter and passing it through to lease_async().

Apply this diff to add the parameter:

 @contextmanager
 def lease(
     self,
     selector: str | None = None,
     lease_name: str | None = None,
     duration: timedelta = timedelta(minutes=30),
+    acquisition_timeout: timedelta | None = None,
 ):
     with start_blocking_portal() as portal:
-        with portal.wrap_async_context_manager(self.lease_async(selector, lease_name, duration, portal)) as lease:
+        with portal.wrap_async_context_manager(
+            self.lease_async(selector, lease_name, duration, portal, acquisition_timeout)
+        ) as lease:
             yield lease
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ced145a and 9393bda.

⛔ Files ignored due to path filters (1)
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (4)
  • packages/jumpstarter-cli/jumpstarter_cli/common.py (4 hunks)
  • packages/jumpstarter-cli/jumpstarter_cli/shell.py (5 hunks)
  • packages/jumpstarter-cli/pyproject.toml (1 hunks)
  • packages/jumpstarter/jumpstarter/config/client.py (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/jumpstarter-cli/pyproject.toml
  • packages/jumpstarter-cli/jumpstarter_cli/shell.py
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: mangelajo
Repo: jumpstarter-dev/jumpstarter PR: 610
File: packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/client.py:488-491
Timestamp: 2025-09-15T08:18:48.571Z
Learning: In the jumpstarter project, code review suggestions should stay focused on the specific scope of the PR. Suggestions about general improvements like timeout handling or error handling that are unrelated to the core changes being made should be avoided, even if they apply to modified code lines.
📚 Learning: 2025-10-14T17:43:07.788Z
Learnt from: michalskrivanek
Repo: jumpstarter-dev/jumpstarter PR: 704
File: packages/jumpstarter/jumpstarter/client/grpc.py:100-107
Timestamp: 2025-10-14T17:43:07.788Z
Learning: In the Jumpstarter client lease model (packages/jumpstarter/jumpstarter/client/grpc.py), `effective_duration` represents the elapsed time for an active lease so far, not the total duration. To calculate expected release time, use `effective_begin_time + duration` (where `duration` is the configured/requested duration), not `effective_begin_time + effective_duration`.

Applied to files:

  • packages/jumpstarter/jumpstarter/config/client.py
📚 Learning: 2025-09-15T08:18:48.571Z
Learnt from: mangelajo
Repo: jumpstarter-dev/jumpstarter PR: 610
File: packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/client.py:488-491
Timestamp: 2025-09-15T08:18:48.571Z
Learning: In the jumpstarter project, code review suggestions should stay focused on the specific scope of the PR. Suggestions about general improvements like timeout handling or error handling that are unrelated to the core changes being made should be avoided, even if they apply to modified code lines.

Applied to files:

  • packages/jumpstarter-cli/jumpstarter_cli/common.py
🔇 Additional comments (7)
packages/jumpstarter/jumpstarter/config/client.py (3)

258-258: LGTM! Clean signature extension.

The optional acquisition_timeout parameter integrates well with the existing lease_async signature and enables callers to override the configured timeout on a per-call basis.


267-272: LGTM! Correct conversion and fallback logic.

The conditional conversion from timedelta to seconds with fallback to the configured default is well-implemented. The minimum validation (≥5 seconds) is appropriately enforced in the CLI and model layers.


285-285: LGTM! Correct parameter passing.

The computed acquisition_timeout_seconds value is correctly passed to the Lease constructor.

packages/jumpstarter-cli/jumpstarter_cli/common.py (4)

6-6: LGTM! Import enables humanized duration parsing.

The pytimeparse2 import provides the enhanced duration parsing capability that supports human-readable formats like "1h30m" and "3h40m".


19-21: LGTM! Clean implementation of minimum validation support.

The __init__ method properly stores the optional minimum duration constraint, enabling enforcement in the convert method.


23-71: LGTM! Comprehensive duration parsing with backward compatibility.

The enhanced convert method implements a robust multi-level parsing strategy:

  1. Direct timedelta pass-through
  2. Integer as seconds (backward compatibility)
  3. String parsing: plain integer → pytimeparse2 → pydantic/ISO 8601
  4. Minimum validation enforcement

The fallback chain maintains backward compatibility while adding rich human-readable format support. Error messages are clear and provide helpful examples.


116-128: LGTM! Well-defined acquisition timeout option.

The new ACQUISITION_TIMEOUT constant and opt_acquisition_timeout option are cleanly implemented:

  • Minimum of 5 seconds aligns with the model-layer constraint
  • Clear help text with examples and requirement documentation
  • Default of None enables fallback to configured timeout
  • Consistent with existing CLI option patterns

Comment on lines +85 to 90
Human-readable: 30m, 3h30m, 1d, 1d3h40m, etc.
ISO 8601: PT1H30M, P1DT2H30M, etc.
Time format: 01:30:00, 2 days, 01:30:00, etc.

See https://docs.rs/speedate/latest/speedate/ for details
See https://github.com/wroberts/pytimeparse2 for details
""",
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.

⚠️ Potential issue | 🟡 Minor

Clarify the time format examples.

Line 87 reads "Time format: 01:30:00, 2 days, 01:30:00, etc." which appears to list "01:30:00" twice. Consider clarifying whether these are meant as:

  • Two examples: "01:30:00" and "2 days, 01:30:00" (compound format)
  • Or separate examples with an accidental duplicate

Suggested clarification:

-Time format: 01:30:00, 2 days, 01:30:00, etc.
+Time format: 01:30:00, or compound like '2 days, 01:30:00', etc.
🤖 Prompt for AI Agents
In packages/jumpstarter-cli/jumpstarter_cli/common.py around lines 85 to 90, the
"Time format" examples are ambiguous and currently show "01:30:00" twice; update
the docstring to remove the duplicate and clarify intended examples (either list
separate examples like "01:30:00" and "2 days, 01:30:00" or show a compound
example "2 days, 01:30:00") so the examples are unambiguous and consistent with
the other formats.

auto-merge was automatically disabled November 17, 2025 11:41

Pull Request is not mergeable

auto-merge was automatically disabled November 17, 2025 11:41

Pull Request is not mergeable

@mangelajo mangelajo enabled auto-merge November 19, 2025 14:08
@mangelajo
Copy link
Copy Markdown
Member Author

the tests did not run for some reason, outages?

@mangelajo
Copy link
Copy Markdown
Member Author

Just bumped the commit message to see if tests would trigger now.

@mangelajo mangelajo merged commit 66691f4 into main Nov 19, 2025
18 checks passed
@mangelajo mangelajo deleted the acquisition-timeout branch November 19, 2025 14:27
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants