router: align SSE to canonical /api/{domain}/events (drop sse.json, derive from x-sse) #120
Labels
No labels
prio_critical
prio_low
type_bug
type_contact
type_issue
type_lead
type_question
type_story
type_task
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
lhumina_code/hero_router#120
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?
Summary
hero_router's SSE handling diverges from the hero_lib macro/SDK canonical (
GET /api/{domain}/events) and is internally inconsistent — it uses three different conventions, none of which match canonical. The fix is router-side alignment, not services growingsse.jsonstubs.Evidence
Router (on
development, post-#118) — three inconsistent conventions:GET /api/main/sse.json, descriptor hardcodedpath = "/api/main/sse.json"— one per socket, not per-domain.crates/hero_router/src/probe.rs:474-485,crates/hero_router/src/scanner.rs:371-385./events(no filter key).crates/hero_router/src/server/multiplex.rs:429./api/{domain}/events→ socket/api/{domain}/sse.json.crates/hero_router/src/server/proxy/http/http_dispatch.rs:296-298.SseDescriptordoc even says "conforming services use/events" — contradicting its own probe.crates/hero_router/src/cache.rs:152-159.hero_lib canonical (unambiguous) —
GET /api/{domain}/events, forwarded verbatim:/api/{domain}/events→ socket/api/{domain}/events, no rename:hero_lib/crates/hero_lifecycle/src/webserver/components/openrpc_proxy/router.rs:245(+ single-domain/api/eventsat:206).GET /{prefix}/api/{domain}/events → socket GET /api/{domain}/events(.../service_proxy/mod.rs:16).@sse(endpoint)defaults to/events; the spec carries anx-sseextension withendpoint,emits,done, and a filter key. Example (demo servergenerated/openrpc/openrpc_dom1.json):"x-sse": { "endpoint": "/events", filter=topic, ... }. There is nosse.jsonanywhere in the canonical.Why NOT "fix" this on the service side
SSE is per-(domain, method) with a filter, not per-socket:
?job_sid=); there is no global proc stream.dom1is per-topic (?topic=);dom2is an unfiltered firehose.The router's probe (
/api/main/sse.json) and multiplexer (bare/events) connect with no filter, so for proc there is nothing meaningful to emit. Satisfying them would mean adding an empty keepalivesse.jsonstub purely to pass the probe — cargo-culting a channel hero_lib already abandoned. Do not addsse.jsonstubs to hero_proc (or any service).Proposed design (router-side)
Drive SSE from the cached per-domain spec (the per-domain
domain_specsadded in #118), not from a probe:/api/{domain}/eventsverbatim to the socket (match hero_lib's proxy).http_dispatch.rs:296-298.sse.jsonprobe — derive SSE channels from each domain spec'sx-sseextension (endpoint + filter key + emits/done), per(domain, method). Removesprobe_events/EventsProbeblind probing.probe.rs,scanner.rs.SseDescriptorfrom one-per-socket (/api/main/sse.json) to per-(domain, method) carrying the filter key.cache.rs:152-159.GET /api/{domain}/events?<filter>=<value>on demand instead of a global bare/events.multiplex.rs:429. (The unfiltered/global case stays valid only where a domain actually exposes a firehose.)Scope / notes
domain_specscache.Implemented — PR #121 (development_router_sse_canonical → development).
/api/{domain}/eventsverbatim (dropped thesse.jsonrename)x-sse(per-domain {channel,domain,endpoint,filter_key};Vecper service); removed thesse.jsonprobe +EventsProbe?<filter>=No service changes (no sse.json stubs). Verified live against the real
hero_demo_server: dom1/api/dom1/eventsfilter=topic, dom2/api/dom2/eventsfirehose; verbatim/eventsforwards 200; oldsse.json404.