Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add retries to Help proxy request #489

Merged
merged 2 commits into from
Aug 28, 2024
Merged

Conversation

juliasilge
Copy link
Contributor

Addresses posit-dev/positron#3753

Folks in that issue ⤴️ are experiencing problems seeing R Help pages in the Help pane. Some things we can notice:

  • None of us internally have been able to reproduce the problem.
  • Some folks do occasionally see the Help page they are querying for! Seems like an intermittent problem.
  • We see errors in logs like "operation was canceled: connection closed before message completed".
  • Some folks have their problems totally solved after installing a new version of Positron.

Given all that, seems like we may just need to retry the request, or at the least that is a first possible step as outlined by @DavisVaughan in posit-dev/positron#3753 (comment).

Comment on lines +256 to +274

// Conversion helper between reqwest and actix-web's `HeaderValue`
//
// Both point to a re-exported `HeaderValue` from the http crate, but they come from
// different versions of the http crate, so they look different to Rust and we need a
// small conversion helper.
// - reqwest re-exports http 1.0.0's `HeaderValue`
// - actix-web re-exports http 0.2.7's `HeaderValue`
fn convert_header_value(x: &reqwest::header::HeaderValue) -> actix_web::http::header::HeaderValue {
let out = actix_web::http::header::HeaderValue::from_bytes(x.as_bytes());

// We've checked these are the same underlying structure, so assert that this works.
let mut out = out.unwrap();

// Set the one other field that defaults to `false`, just in case.
out.set_sensitive(x.is_sensitive());

out
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Joint work with @DavisVaughan who discovered that:

  • actix-web re-exports http 0.2.7's HeaderValue
  • reqwest re-exports http 1.0.0's HeaderValue

Here is the commit where reqwest changed this:
seanmonstar/reqwest@eb94f26

Comment on lines 135 to 140
// Set up reqwest client with 3 retries.
let retry_policy = ExponentialBackoff::builder().build_with_max_retries(3);
let client = ClientBuilder::new(Client::new())
.with(RetryTransientMiddleware::new_with_policy(retry_policy))
.build();

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shall we start with 3 retries?

Comment on lines +20 to +23
use reqwest::Client;
use reqwest_middleware::ClientBuilder;
use reqwest_retry::policies::ExponentialBackoff;
use reqwest_retry::RetryTransientMiddleware;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reqwest crate doesn't have any retry mechanism, but we can use these related crates to set up middleware and retries.

Comment on lines +45 to +46
reqwest-retry = "0.6.1"
reqwest-middleware = "0.3.3"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good news is that both reqwest-retry and reqwest-middleware are smart enough to set default-features = false for their reqwest dependency
https://github.com/TrueLayer/reqwest-middleware/blob/6cd4eb93f8567bece4526f050cd6f7c2bde7371e/reqwest-middleware/Cargo.toml#L24
https://github.com/TrueLayer/reqwest-middleware/blob/6cd4eb93f8567bece4526f050cd6f7c2bde7371e/reqwest-retry/Cargo.toml#L19

Making #487 still viable even after this

Copy link
Contributor

@DavisVaughan DavisVaughan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems right to me

crates/ark/src/help_proxy.rs Outdated Show resolved Hide resolved
@@ -128,8 +132,14 @@ async fn proxy_request(req: HttpRequest, app_state: web::Data<AppState>) -> Http
// Add query from original request back to URL.
target_url.set_query(Some(query));

// Set up reqwest client with 3 retries.
let retry_policy = ExponentialBackoff::builder().build_with_max_retries(3);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Co-authored-by: Davis Vaughan <davis@rstudio.com>
@juliasilge juliasilge merged commit 653f4c3 into main Aug 28, 2024
3 checks passed
@juliasilge juliasilge deleted the reqwest-middleware-retry branch August 28, 2024 19:00
@github-actions github-actions bot locked and limited conversation to collaborators Aug 28, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants