refactor #15
Labels
No labels
prio_critical
prio_low
type_bug
type_contact
type_issue
type_lead
type_question
type_story
type_task
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
lhumina_code/hero_router#15
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
hero_router_server
hero_router_ui
skills to use
/hero_sockets
Implementation Spec — Issue #15: Refactor
Objective
Decouple
hero_router_uifrom its own independent socket scanner and make it consume service data fromhero_router_servervia proxied RPC calls to the server socket. Makehero_router_uia pure dashboard consumer. Also enforce thatui.socksockets are HTML-only during probing.What is already done
hero_router_server(9998) runsbuild_proxy_router— all/<service>/rpc,/<service>/admin,/:webnameroutinghero_router_ui(9997) runsbuild_dashboard_router— HTML dashboard only, no proxy routes/rpcderive_group_namecorrectly handles per-service pathsWhat still needs to be done
Step 1 — Fix
probe_ui_socketto be HTML-onlyFile:
crates/hero_router/src/scanner.rsRemove
try_http_openrpc_discovercall fromprobe_ui_socket.ui.sockis HTML-only by spec. Remove the OpenRPC probing block — onlycheck_health+fetch_heroservice_manifest+check_serves_html. Always assignprotocols = vec![ServiceProtocol::Web].Step 2 — Add
server_socketfield toAppStateFile:
crates/hero_router/src/server/routes.rsAdd
pub server_socket: Option<String>toAppState. WhenSome(path), the dashboard RPC/SSE handlers proxy to that socket instead of dispatching locally.build_proxy_routersets it toNone;build_dashboard_routerreceives it as part ofAppState.Step 3 — Proxy
/rpcinbuild_dashboard_routerFile:
crates/hero_router/src/server/routes.rsIn
rpc_handler: whenstate.server_socketisSome(path), forward the raw POST body topathat/rpcusing the existingproxy_to_socketinfrastructure. Return the proxied response. WhenNone, dispatch locally as now.For
/api/eventsSSE: update the dashboard JS (EventSource) to point athttp://localhost:9998/api/eventsdirectly (CORS is open) rather than bridging in Rust.Step 4 — Remove scanner/cache from
hero_router_uiFile:
crates/hero_router_ui/src/main.rsRemove:
Scanner,RouterCache,Manifest,SseBroadcaster,RpcStateconstruction,spawn_discoverycalls, and the self-registration block. The UI only needsRouterConfig,SocketProxy, andHeroUiServer. Passserver_socket = Some(cfg.server_socket_path_flat().to_string_lossy().to_string())intoAppState.Step 5 — Move self-registration to server
File:
crates/hero_router_server/src/main.rsMove the "Hero Router" self-registration block (pinned
ServiceEntry) from the UI into the server'sbuild_and_start.Acceptance Criteria
probe_ui_socketnever callstry_http_openrpc_discoverhero_router_uicontains noScanner,RouterCache, orRpcStateconstruction/rpccalls proxy tohero_router_server.sockhero_router_server, nothero_router_uicargo build --workspacepassesTest Results
Date: 2026-04-06
Status: PASS
Summary
All tests passed. The workspace compiled successfully in 13.19s.
Crates Tested
hero_router_exampleshero_router_sdkhero_router_serverhero_router_uiherolib_routerhero_router(bin)Doc Tests
hero_router_exampleshero_router_sdkherolib_routerCommand
Output
Implementation committed:
5a1ae0fBrowse:
5a1ae0fChanges
scanner.rs—probe_ui_socketis now HTML-only (removed OpenRPC probing fromui.sock)routes.rs—AppStategainsserver_socket: Option<String>;rpc_handlerproxies to server when sethero_router_server/main.rs— self-registration moved from UI to server (authoritative cache owner)hero_router_ui/main.rs—spawn_discoveryremoved; replaced withspawn_cache_sync(SDK-based 30s sync from server);/rpcproxies tohero_router_server.sockhero_router_ui/Cargo.toml— addedhero_router_sdkdependency