Skip to content

Commit

Permalink
Make http timeout configurable (#5532)
Browse files Browse the repository at this point in the history
## Problem

Currently http timeout is hardcoded to 15 seconds.

## Summary of changes

Added an option to configure it via cli args.

Context: https://neondb.slack.com/archives/C04DGM6SMTM/p1696941726151899
  • Loading branch information
khanova authored Oct 12, 2023
1 parent ddceb9e commit dbb21d6
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 5 deletions.
9 changes: 8 additions & 1 deletion proxy/src/bin/proxy.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use futures::future::Either;
use proxy::auth;
use proxy::config::HttpConfig;
use proxy::console;
use proxy::http;
use proxy::metrics;
Expand Down Expand Up @@ -79,6 +80,9 @@ struct ProxyCliArgs {
/// Allow self-signed certificates for compute nodes (for testing)
#[clap(long, default_value_t = false, value_parser = clap::builder::BoolishValueParser::new(), action = clap::ArgAction::Set)]
allow_self_signed_compute: bool,
/// timeout for http connections
#[clap(long, default_value = "15s", value_parser = humantime::parse_duration)]
sql_over_http_timeout: tokio::time::Duration,
}

#[tokio::main]
Expand Down Expand Up @@ -220,12 +224,15 @@ fn build_config(args: &ProxyCliArgs) -> anyhow::Result<&'static ProxyConfig> {
auth::BackendType::Link(Cow::Owned(url))
}
};

let http_config = HttpConfig {
sql_over_http_timeout: args.sql_over_http_timeout,
};
let config = Box::leak(Box::new(ProxyConfig {
tls_config,
auth_backend,
metric_collection,
allow_self_signed_compute: args.allow_self_signed_compute,
http_config,
}));

Ok(config)
Expand Down
5 changes: 5 additions & 0 deletions proxy/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ pub struct ProxyConfig {
pub auth_backend: auth::BackendType<'static, ()>,
pub metric_collection: Option<MetricCollectionConfig>,
pub allow_self_signed_compute: bool,
pub http_config: HttpConfig,
}

#[derive(Debug)]
Expand All @@ -26,6 +27,10 @@ pub struct TlsConfig {
pub common_names: Option<HashSet<String>>,
}

pub struct HttpConfig {
pub sql_over_http_timeout: tokio::time::Duration,
}

impl TlsConfig {
pub fn to_server_config(&self) -> Arc<rustls::ServerConfig> {
self.config.clone()
Expand Down
7 changes: 4 additions & 3 deletions proxy/src/http/sql_over_http.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ use url::Url;
use utils::http::error::ApiError;
use utils::http::json::json_response;

use crate::config::HttpConfig;
use crate::proxy::{NUM_CONNECTIONS_ACCEPTED_COUNTER, NUM_CONNECTIONS_CLOSED_COUNTER};

use super::conn_pool::ConnInfo;
Expand All @@ -49,7 +50,6 @@ enum Payload {

const MAX_RESPONSE_SIZE: usize = 10 * 1024 * 1024; // 10 MiB
const MAX_REQUEST_SIZE: u64 = 10 * 1024 * 1024; // 10 MiB
const HTTP_CONNECTION_TIMEOUT: tokio::time::Duration = tokio::time::Duration::from_secs(15);

static RAW_TEXT_OUTPUT: HeaderName = HeaderName::from_static("neon-raw-text-output");
static ARRAY_MODE: HeaderName = HeaderName::from_static("neon-array-mode");
Expand Down Expand Up @@ -191,9 +191,10 @@ pub async fn handle(
sni_hostname: Option<String>,
conn_pool: Arc<GlobalConnPool>,
session_id: uuid::Uuid,
config: &'static HttpConfig,
) -> Result<Response<Body>, ApiError> {
let result = tokio::time::timeout(
HTTP_CONNECTION_TIMEOUT,
config.sql_over_http_timeout,
handle_inner(request, sni_hostname, conn_pool, session_id),
)
.await;
Expand Down Expand Up @@ -224,7 +225,7 @@ pub async fn handle(
Err(_) => {
let message = format!(
"HTTP-Connection timed out, execution time exeeded {} seconds",
HTTP_CONNECTION_TIMEOUT.as_secs()
config.sql_over_http_timeout.as_secs()
);
error!(message);
json_response(
Expand Down
9 changes: 8 additions & 1 deletion proxy/src/http/websocket.rs
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,14 @@ async fn ws_handler(
// TODO: that deserves a refactor as now this function also handles http json client besides websockets.
// Right now I don't want to blow up sql-over-http patch with file renames and do that as a follow up instead.
} else if request.uri().path() == "/sql" && request.method() == Method::POST {
sql_over_http::handle(request, sni_hostname, conn_pool, session_id).await
sql_over_http::handle(
request,
sni_hostname,
conn_pool,
session_id,
&config.http_config,
)
.await
} else if request.uri().path() == "/sql" && request.method() == Method::OPTIONS {
Response::builder()
.header("Allow", "OPTIONS, POST")
Expand Down

1 comment on commit dbb21d6

@github-actions
Copy link

Choose a reason for hiding this comment

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

2348 tests run: 2226 passed, 0 failed, 122 skipped (full report)


Flaky tests (2)

Postgres 16

  • test_competing_branchings_from_loading_race_to_ok_or_err: debug

Postgres 14

  • test_crafted_wal_end[last_wal_record_xlog_switch_ends_on_page_boundary]: debug

Code coverage (full report)

  • functions: 52.5% (8183 of 15601 functions)
  • lines: 81.1% (47780 of 58924 lines)

The comment gets automatically updated with the latest test results
dbb21d6 at 2023-10-12T10:32:54.220Z :recycle:

Please sign in to comment.