leptos: Leptos Axum Handle Server Fn unwrapping Context can panic under load
Describe the bug In leptox_axum handle_server_fns_inner there are several call to unwrap() that can evidently be None (though I’m not entirely sure how).
// If ResponseOptions are set, add the headers and status to the request
let res_options = use_context::<ResponseOptions>();
// if this is Accept: application/json then send a serialized JSON response
let accept_header = headers
.get("Accept")
.and_then(|value| value.to_str().ok());
let mut res = Response::builder();
// Add headers from ResponseParts if they exist. These should be added as long
// as the server function returns an OK response
let res_options_outer = res_options.unwrap().0; -----> unwrap a none
let res_options_inner = res_options_outer.read();
called `Result::unwrap()` on an `Err` value: Canceled
thread '<unnamed>' panicked at .cargo/registry/src/index.crates.io-6f17d22bba15001f/leptos_axum-0.5.4/src/lib.rs:323:61:
Leptos Dependencies
leptos = { version = "0.5", features = ["nightly"] }
leptos_axum = { version = "0.5", optional = true }
leptos_meta = { version = "0.5", features = ["nightly"] }
leptos_router = { version = "0.5", features = ["nightly"] }
To Reproduce Steps to reproduce the behavior: You’ll have to bear with me here because I can only reproduce this when stress testing.
- run your benchmarking tool of choice
./wrk -t 8 -c 2000 -d 30s --latency http://localhost:3000
- go anywhere on your app that makes a call to a server fn (and has IO like a database call or sleep) and uses extractors).
- start spamming refresh until
error reaching server to call server function: TypeError: NetworkError when attempting to fetch resource.
.
Expected behavior Option::unwrap() call is removed and replaced with a guard. Though I’m not sure what is causing this problem.
Screenshots If applicable, add screenshots to help explain your problem.
Additional context If you look at the handler you can clearly see that provide_context is called early on so there’s no reason to suspect that getting the context for ResponseOptions wouldn’t return Some, but it does). My guess bet is that there’s reads and writes going on at the same time.
About this issue
- Original URL
- State: open
- Created 7 months ago
- Reactions: 1
- Comments: 22 (3 by maintainers)
Commits related to this issue
- fix: increase memory for app process - see https://github.com/leptos-rs/leptos/issues/2112 — committed to picture-pro/mono by johnbchron 4 months ago
@mjarvis9541 @glademiller I’m concerned that the solution (which I believe is now merged in #2468) mostly hides the problem rather than fixing it: i.e., if someone has a server function that actually sets something in
ResponseOptions
,unwrap_or_default()
(or printing a warning as #2468 does) doesn’t panic but returns a response and fails to set that header/status code/etc. that was supposed to be set in the response. I guess it’s better than the panic.I will plan to revisit this to make sure it is solved in 0.7, where the reactive system works significantly differently.
I can confirm this completely resolves the issue. This has been happening on multiple production apps I’ve built and released to a server, I never have been able to reproduce this locally.
@gbj this is the issue I brought up in discord regarding the 502 errors through a load balancer. I never did get to the bottom of why that was happening but the above has resolved that also.
@Panaetius I’m happy to look into this at some point if you can open a new issue with some way of reproducing the problem.
@WIGGLES-dev @pnmadelaine Now that #2158 is merged, the server fn implementation on the main branch is now quite different from the previous implementation. It is available for testing either with a dependency on the main branch or version
0.6.0-beta
.Because the underlying implementation has changed significantly, I’m going to close this issue. If you encounter the same problem with the new version, feel free to open a new issue.