DSH HUB
HomePlugin StorePlugin PacksCommunityRankingsResourcesPublish Guide
Plugin source
Back to catalog

drindr /

dsh-rerun

Topic repository only

embed Rerun into DSH

★ 0 Stars0 Forks0 IssuesN/A Community rating0 Confirmed installs
View on GitHub
READMESource: main@7df44cca

dsh-rerun

Embed the Rerun web viewer in the dsh web GUI: browse .rrd recordings from the workspace root and connect to live rerun --serve streams — all inside the harness, fully offline.

What it does

  • A Rerun button in the sidebar footer opens a full-window overlay.
  • Recordings mode lists .rrd / .rrd.zst files under the workspace root (env override: DSH_RERUN_RECORDINGS_DIR) and renders the selected one.
  • Live mode connects the viewer to a running Rerun server, e.g. started with rerun --serve-web (note: the flag is --serve-web, not --serve). The default URL is shown/edited in the namespaced alias form rerun+<page-scheme>://<page-host>/dsh-rerun/live — the same origin as the GUI. Because it is same-origin there is no CORS and no mixed content, so Live works on any GUI access scheme — http://127.0.0.1:3080, http://<host>, or https://<host>. How the 0.34.1 viewer actually connects (verified via Network capture):
    • the URL is only a parse token: the viewer accepts live URLs whose path is exactly /proxy (host/scheme free; any other path — including the /dsh-rerun/live alias — fails as "Failed to parse URL"),
    • the real connection is grpc-web to <origin>/rerun.sdk_comms.v1alpha1.MessageProxyService/<Method> (OPTIONS preflight + POST streaming) — /proxy itself is never fetched. The panel therefore speaks the alias and maps it to the canonical /proxy path before the viewer sees it (canonicalLiveUrl in src/client/store.ts); typing the canonical form directly also works. The host half registers a passthrough to the rerun server (http://127.0.0.1:9876, env override: DSH_RERUN_LIVE_ORIGIN) at both /rerun.sdk_comms.v1alpha1.MessageProxyService/* (the actual live stream) and /proxy / /dsh-rerun/live/* (parse-token safety + legacy URLs). On an https page the one remaining prerequisite is that the browser trusts the GUI's TLS certificate — fetch has no "proceed anyway" path (page loads can be bypassed, fetches cannot). Until it is trusted the panel shows a 证书不受信任 hint. One-time trust for Caddy's internal CA:
    sudo cp ~/.local/share/caddy/pki/authorities/local/root.crt /usr/local/share/ca-certificates/
    sudo update-ca-certificates
    

    (or import root.crt into the browser's CA store), then restart the browser.

How it stays light (lazy load + local cache)

The viewer is a 48 MB WASM binary. This plugin never ships it in the client bundle and never hits a CDN:

  • The host half serves the viewer straight out of the installed @rerun-io/web-viewer npm package (a plain dependency → package-manager cache = local disk cache). See src/index.ts → findViewerRoot.
  • The client half only carries an 8 KB panel UI. The viewer iframe — and therefore every viewer byte — is fetched only when the overlay opens.
  • Versioned asset URLs (/dsh-rerun/viewer/0.34.1/…) are served with Cache-Control: immutable, so after the one-time 48 MB fetch every re-open is instant from the browser cache. The wasm response also sets rerun-final-length so the viewer shows a download progress bar.

Version alignment

@rerun-io/web-viewer@0.34.1 matches the local rerun-cli 0.34.1. Keep the dependency in lockstep with the Rerun SDK/CLI that produces your .rrd files (the viewer reads files from the previous minor version and speaks the matching gRPC protocol for live streaming).

Live operations & troubleshooting

Quick start for a live demo with data streaming in real time:

rerun --serve-web                  # gRPC server on :9876 (+ web viewer on :9090)
python feed-live.py                # any rerun SDK: connect_grpc + rr.log in a loop
                                   # or: rerun --serve-web demo-dna.rrd  (pre-loaded file)

rerun-sdk 0.36 API changes vs older docs: connect → connect_grpc, set_time_sequence → set_time(..., sequence=), Scalar → Scalars.

Stream connection hygiene — the /proxy passthrough is a long-lived stream, and the viewer drops it whenever the overlay closes. The host half destroys the upstream connection on client close (res.on('close') → proxyReq.destroy()); without that, every closed viewer leaks one idle TCP connection into the rerun server. Symptoms of the leak: the viewer renders an empty light screen and the rerun server log fills with re_quota_channel: Sender has been blocked for over 5 seconds…. Diagnosis: ss -tn | grep 9876 shows a client socket with a multi-MB Send-Q/Recv-Q that never drains. Leaked sockets live in the dsh web process, so they survive rerun server restarts — clearing them requires a dsh web restart (which also loads any rebuilt lib/index.js).

Note that the rerun server and the data feeder are external processes, not owned by the plugin — if Live shows an empty screen, check they are still up (ss -tln | grep 9876) before anything else.

Host routes

Route Purpose
GET /dsh-rerun/viewer/<version>/ iframe entry page
GET /dsh-rerun/viewer/<version>/index.js, re_viewer.js, re_viewer_bg.wasm viewer assets (immutable)
GET /dsh-rerun/recordings/<rel>.rrd workspace recording (traversal-safe)
GET /dsh-rerun/api/recordings { recordings[], viewerVersion }
GET /dsh-rerun/api/health { ok, viewerVersion, recordingsRoot }

Routes mount on the existing web server (ctx.webServer.register), so there is no second port and no CORS. Same-origin iframe → no CORS shenanigans.

Build

pnpm install --store-dir <writable-store> --cache-dir <writable-cache>  # sandbox note below
node build.mjs       # -> lib/index.js (host ESM) + lib/client.js (browser CJS)
node watch.mjs       # dev watcher (optional)

Sandbox note: pnpm's default store sqlite cannot open under the harness file sandbox; point --store-dir/--cache-dir at a writable location (the repo uses .pnpm-store / .pnpm-cache).

Wiring into a profile

  1. ln -s <repo>/dsh-rerun $DSH_HOME/plugins/dsh-rerun
  2. Add "dsh-rerun": "link:../../plugins/dsh-rerun" to the profile's package.json dependencies and pnpm install.
  3. Add a loader entry to the profile's cordis.patch.yml:
    - insert:
        - id: rerun
          name: dsh-rerun
    
  4. Restart dsh web — new plugins are loader entries fixed at boot.

Dev iteration after restart

  • lib/client.js changes hot-swap without a page refresh (dsh-client-hmr polls the bundle).
  • lib/index.js changes need an hmr watch row covering this package's real path in the profile's cordis.patch.yml, otherwise a dsh web restart.
—/ 5

No ratings yet

Manifest verification required

Commit 7df44ccaee04

Community comments

No comments yet. Be the first to write one.

DSH HUB

A community index for DSH plugins. Not an official GitHub or DeepSeek AI product.

CommunityResourcesAPIAbout