Skip to content

Commit

Permalink
Added tower-http layers to improve client-side experience
Browse files Browse the repository at this point in the history
  • Loading branch information
ezrasingh committed Aug 12, 2024
1 parent bf1e595 commit c483159
Show file tree
Hide file tree
Showing 8 changed files with 146 additions and 6 deletions.
95 changes: 95 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions contrib/docker/quickstart/geoprox.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
http_addr = '0.0.0.0'
# The port the server will listen on
http_port = 5000
# Timeout duration in seconds
timeout = 10

[shard]
# Determines the default geohash length for inserts
Expand Down
1 change: 1 addition & 0 deletions geoprox-server/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

- Added support for `Accept-Encoding`(via [`compression-full`](https://docs.rs/crate/tower-http/0.5.2/features#compression-full) feature in `tower-http`) and `Content-Encoding`(via [`decompression-full`](https://docs.rs/crate/tower-http/0.5.2/features#decompression-full) feature in `tower-http`) headers, [timeouts](https://docs.rs/crate/tower-http/0.5.2/features#timeout) and [tracing](https://docs.rs/crate/tower-http/0.5.2/features#trace) in responses.
- Added support for path normalization (i.e trailing slash or no trailing slash) ([#4](https://github.com/ezrasingh/geoprox/issues/4))

## 0.4.1
Expand Down
9 changes: 8 additions & 1 deletion geoprox-server/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,14 @@ serde = { version = "1.0.199", features = ["derive", "rc"] }
serde_json = "1.0.116"
tokio = { version = "1.37.0", features = ["full"] }
tower = "0.4.13"
tower-http = { version = "0.5.2", features = ["fs", "trace", "normalize-path"] }
tower-http = { version = "0.5.2", features = [
"fs",
"trace",
"timeout",
"compression-full",
"decompression-full",
"normalize-path",
] }
tracing = "0.1.40"
tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }
utoipa = { version = "4.2.3", features = ["axum_extras"] }
Expand Down
8 changes: 6 additions & 2 deletions geoprox-server/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,24 @@ use std::net::{IpAddr, Ipv4Addr, SocketAddr};

pub const DEFAULT_ADDR: IpAddr = IpAddr::V4(Ipv4Addr::UNSPECIFIED);
pub const DEFAULT_PORT: u16 = 5000;
pub const DEFAULT_TIMEOUT: u64 = 10;

#[derive(Clone, Debug, Deserialize)]
pub struct ServerConfig {
/// The address the server will bind to
/// The address the server will bind to (default 0.0.0.0)
pub http_addr: Option<std::net::IpAddr>,
/// The port the server will listen on
/// The port the server will listen on (default 5000)
pub http_port: Option<u16>,
/// Timeout duration in seconds (default 10)
pub timout: Option<u64>,
}

impl Default for ServerConfig {
fn default() -> Self {
Self {
http_addr: Some(DEFAULT_ADDR),
http_port: Some(DEFAULT_PORT),
timout: Some(DEFAULT_TIMEOUT),
}
}
}
Expand Down
34 changes: 31 additions & 3 deletions geoprox-server/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,15 @@ use app::AppState;
use config::ServerConfig;
use geoprox_core::models::GeoShardConfig;

use axum::extract::Request;
use axum::routing::Router;
use axum::{body::Bytes, extract::Request};
use std::time::Duration;
use tower::Layer;
use tower_http::normalize_path::NormalizePathLayer;
use tower_http::compression::CompressionLayer;
use tower_http::decompression::DecompressionLayer;
use tower_http::timeout::TimeoutLayer;
use tower_http::trace::{DefaultMakeSpan, DefaultOnResponse};
use tower_http::{normalize_path::NormalizePathLayer, trace::TraceLayer};
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};

/// Start http server
Expand All @@ -29,7 +34,30 @@ pub async fn run(server_config: ServerConfig, shard_config: GeoShardConfig) {
let state = AppState::new(server_config.clone(), shard_config);
let router = Router::new()
.nest("/api/v1/", api::routes(state))
.merge(api::docs::router());
.merge(api::docs::router())
.layer(
tower::ServiceBuilder::new()
.layer(
// Add high level tracing/logging to all requests
TraceLayer::new_for_http()
.on_body_chunk(|chunk: &Bytes, latency: Duration, _: &tracing::Span| {
tracing::trace!(size_bytes = chunk.len(), latency = ?latency, "sending body chunk")
})
.make_span_with(DefaultMakeSpan::new().include_headers(true))
.on_response(DefaultOnResponse::new()
.include_headers(true).
latency_unit(tower_http::LatencyUnit::Micros)
),
)
// Set a timeout
.layer(TimeoutLayer::new(
Duration::from_secs(server_config.timout.unwrap_or(config::DEFAULT_TIMEOUT)))
)
// Compress responses
.layer(CompressionLayer::new())
// Decompress requests
.layer(DecompressionLayer::new())
);

// normalize paths on all routes
let router = NormalizePathLayer::trim_trailing_slash().layer(router);
Expand Down
2 changes: 2 additions & 0 deletions geoprox/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ Here's an example configuration file in `TOML` format:
http_addr = '0.0.0.0'
# The port the server will listen on
http_port = 5000
# Timeout duration in seconds
timeout = 10

[shard]
# Determines the default geohash length for inserts
Expand Down
1 change: 1 addition & 0 deletions geoprox/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ fn main() {
ServerConfig {
http_addr: Some(socket.ip()),
http_port: Some(socket.port()),
..server_conf
},
shard_conf,
)
Expand Down

0 comments on commit c483159

Please sign in to comment.