fix(embedder): proxy openrpc returns 502 JSON + EmbedderdClient async #25
No reviewers
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_embedder!25
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "development_proxy_openrpc_error"
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
Two related fixes in the embedder backend, both about returning structured JSON / not panicking when something is off.
1.
embedder_proxy::openrpc_handlerno longer silently masks upstream failures (closes #21)openrpc_handlerpreviously returned200 OK+"{}"when the upstream OpenRPC GET failed. It now matches the existing error pattern from the same file'sPOST /rpchandler: HTTP 502 +Content-Type: application/json+{"error": {"message": "Failed to fetch upstream OpenRPC spec: <e>", "code": "upstream_unavailable"}}. The deadlet _ = forward_to_upstream(_, "")"preserves prior semantics" call (and its 2-line comment) is dropped — its result was always discarded.2.
EmbedderdClientconverted from blocking to async to stop tokio worker panicshero_embedder_serverworker threads were panicking withCannot drop a runtime in a context where blocking is not allowedwheneverembed_cached/rerank_via(called from per-request axum handlers) reached the daemon delegation code. The cause:EmbedderdClientwrappedreqwest::blocking::Client, which spins up an inner tokio runtime per call and panics on drop when there's already a multi-threaded runtime in scope. tokio respawned workers automatically so the server stayed "up", but every panicking request dropped its hyper connection mid-flight, causinghero_routerto return 502 withclient error (SendRequest)to the dashboard.PR #24 already fixed the startup path of this by wrapping
discover_embedderdintokio::task::spawn_blocking, but the per-request paths (embed_cached,rerank_via, all 8 of their callers acrossapi/{embed, index, search, corpus}.rs) were still calling the blocking client directly from async context. This PR converts the entire client + cascade to async:EmbedderdClient::{is_reachable, embed, rerank}are nowasync fnand usereqwest::Client(notreqwest::blocking::Client).AppState::{rerank_via, embed_cached}are nowasync fn; their bodies.awaitthe client calls.api/embed.rs,api/index.rs,api/search.rs(×3),api/corpus.rs(×3) gain.await. Every caller was already in apub async fn handle_*ortokio::spawn(async move { ... })context, so the cascade is clean.discover_embedderdbecomesasync fn; the now-redundanttokio::task::spawn_blocking(discover_embedderd)wrapper from PR #24 is dropped, andstd::thread::sleepbecomestokio::time::sleep.Verification
50/50 sequential
infocalls return 200, zero worker panics in the live binary.Manual proxy verification (issue #21 fix):
Test plan
cargo check --workspace --binsclean (8 crates)cargo test -p hero_embedder_proxy9/9 passingrunningon first try (PR #24's retry-with-backoff still works)infocalls: 50/50 200 OKtokio-rt-workerpanics orCannot drop a runtimein server logs after the patchNotes
embedderd_client.rspreviously claimed "callers spawn_blocking where it matters" — that turned out to be false. The async conversion removes that whole class of bug at the source rather than playing whack-a-mole withspawn_blockingper call site.error.codefor the proxy's openrpc 502 is the string"upstream_unavailable"rather than a JSON-RPC numeric code —/openrpc.jsonis a plain HTTP GET, not a JSON-RPC method, so the-32603namespace doesn't apply there. Thejsonrpc_handlerandraw_rpc_handlerin the same file continue to use-32603for legitimate JSON-RPC envelopes (untouched).Backend unavailable (HTTP 502): … client error (SendRequest)reports surfaced by the merged PR #22's UI fail-soft.fix(embedder_proxy): return 502 JSON when upstream openrpc.json fetch failsto fix(embedder): proxy openrpc returns 502 JSON + EmbedderdClient async