Skip to content

cloudxr: wire client reconnect/warm-up-timeout config through OOB launch - #1145

Open
gareth-morgan-nv wants to merge 1 commit into
gmorgan/passthrough-only-detectionfrom
gmorgan/oob-reliability-config-wiring
Open

gareth-morgan-nv wants to merge 1 commit into
gmorgan/passthrough-only-detectionfrom
gmorgan/oob-reliability-config-wiring

Conversation

@gareth-morgan-nv

Copy link
Copy Markdown
Contributor

Summary

  • client_ui_fields_from_env() only forwarded codec/panelHiddenAtStart from TELEOP_CLIENT_* env vars into the headset bookmark URL. reconnectEnabled, reconnectMaxAttempts, reconnectDelayMs, streamAttachTimeoutMs, and the two new warmupBeginTimeoutMs/warmupEndTimeoutMs props (client-side support added in webxr: detect passthrough-only (stream that never attaches) #1142) had no way to reach a real headset launch - they'd sit at their client-side defaults regardless of what an operator configured.
  • Adds the same env-var -> URL-param forwarding for all five, following the existing codec/panelHiddenAtStart pattern exactly (new TELEOP_CLIENT_RECONNECT_ENABLED, _RECONNECT_MAX_ATTEMPTS, _RECONNECT_DELAY_MS, _STREAM_ATTACH_TIMEOUT_MS, _WARMUP_BEGIN_TIMEOUT_MS, _WARMUP_END_TIMEOUT_MS env vars).
  • build_teleop_url()/build_headset_bookmark_url() needed no other changes - client_ui_fields_from_env()'s output merges into stream_config generically, so new keys flow through the existing pipeline automatically.

Test plan

  • Unit coverage on both boundary functions (client_ui_fields_from_env, build_headset_bookmark_url) in test_oob_teleop_env.py
  • One end-to-end test through build_teleop_url() in test_oob_teleop_adb.py, exercising the full env-var -> bookmark-URL chain, not just its two ends in isolation
  • ruff check/ruff format --check clean on all three touched files
  • pytest tests/python/core/cloudxr/ - 100/100 passing

🤖 Generated with Claude Code

client_ui_fields_from_env() previously only forwarded codec and
panelHiddenAtStart from TELEOP_CLIENT_* env vars into the headset
bookmark URL, so reconnectEnabled, reconnectMaxAttempts,
reconnectDelayMs, streamAttachTimeoutMs, and the two new
warmupBeginTimeoutMs/warmupEndTimeoutMs props (all now supported
client-side, see gmorgan/passthrough-only-detection) had no way to
reach a real headset launch - they'd sit at their client-side
defaults regardless of what an operator configured.

Adds the same env-var -> URL-param forwarding for all five, following
the existing codec/panelHiddenAtStart pattern exactly:

- TELEOP_CLIENT_RECONNECT_ENABLED (bool)
- TELEOP_CLIENT_RECONNECT_MAX_ATTEMPTS (int)
- TELEOP_CLIENT_RECONNECT_DELAY_MS (int)
- TELEOP_CLIENT_STREAM_ATTACH_TIMEOUT_MS (int)
- TELEOP_CLIENT_WARMUP_BEGIN_TIMEOUT_MS (int)
- TELEOP_CLIENT_WARMUP_END_TIMEOUT_MS (int)

build_teleop_url()/build_headset_bookmark_url() needed no other
changes: client_ui_fields_from_env()'s output is merged into
stream_config generically, so the new keys flow through the existing
pipeline automatically.

Tests: unit coverage on both boundary functions
(client_ui_fields_from_env, build_headset_bookmark_url) in
test_oob_teleop_env.py, plus one end-to-end test through
build_teleop_url() in test_oob_teleop_adb.py so the full env-var ->
bookmark-URL chain is exercised, not just its two ends in isolation.

Signed-off-by: Gareth Morgan <gmorgan@nvidia.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Signed-off-by: Gareth Morgan <gmorgan@nvidia.com>
@coderabbitai

coderabbitai Bot commented Sep 29, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository: NVIDIA/IsaacCapture/.coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 09f584ad-b7b4-4758-a174-fb442110352a

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

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

out["panelHiddenAtStart"] = True
elif ph in ("0", "false", "no", "off"):
out["panelHiddenAtStart"] = False
re_enabled = os.environ.get("TELEOP_CLIENT_RECONNECT_ENABLED", "").strip().lower()

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.

actually, I would really prefer us to move away from adding environment vars to gate different behaviors. this really causes lots of unnecessary fragmentation in the user flow.

any reason we don't just make reconnect the default and only behavior?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

As discussed on slack. I think the retry is better done by the OOB system as it can do so more reliably. Though we could also do via the component as well.

gareth-morgan-nv added a commit that referenced this pull request Sep 29, 2026
… builds, add crash/relaunch coverage

Switch every real-browser test from the real @nvidia/cloudxr SDK to
MockCloudXR (npm run build:app-mock): the real SDK genuinely tries to
stream against whatever's on backend_port, which is unpredictable and
gives a test nothing to assert against. MockCloudXR mounts the identical
App.tsx/CloudXRComponent.tsx UI with a fully deterministic, externally
controllable session, and never opens a socket of its own, so
minimal_mock_runtime() is gone entirely.

Switch from a dev-server to a static production build
(static_webxr_build()). Two real bugs made this necessary: webpack HMR
re-executes a module's top-level code on live-reload, creating a second,
disconnected instance of cloudxr-mock-alias.ts's activeSession that
window.__mockCloudXRFail() silently bound to instead of the real running
session; and <React.StrictMode> (present regardless of HMR) double-invokes
effects in a dev-mode build, calling CloudXR.createSession() twice for the
same reason. webpack.app-mock.js now builds in production mode. Along the
way, a stale webpack persistent filesystem cache (keyed only on the config
file, not source files) was found silently serving an old compiled bundle;
static_webxr_build() now clears it before every build.

window.__mockCloudXRFail() gains an optional `code` param: a code-less
failure is "recoverable" per isRecoverable(), and CloudXRComponent.tsx
auto-reconnects on those without ever showing the error banner, so
forcing a real terminal error needs a code in the non-retryable range.

Add two new real-browser tests: one proving the crash-trigger mechanism
itself (a real, deterministic, DOM-visible error banner on demand), and
one anticipatory test written against gmorgan/oob-error-relaunch (#1146)
before that branch has merged here - it asserts on black-box observable
recovery (a second real `am start`, a second real tab) rather than
importing any private function, so it fails cleanly on that assertion
today and should turn green once #1146 lands. Also add
test_build_teleop_url_forwards_reliability_config_from_env, the same
"write it now, let it fail until merged" idea applied to
gmorgan/oob-reliability-config-wiring (#1145)'s plain env-var/string
forwarding - no browser needed for that one.

Signed-off-by: Gareth Morgan <gmorgan@nvidia.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Signed-off-by: Gareth Morgan <gmorgan@nvidia.com>

This branch has not been deployed

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants