This commit is contained in:
Elijah McMorris 2023-07-23 01:48:43 +00:00
parent a46121adc7
commit 6a953c100f
Signed by: NexVeridian
SSH key fingerprint: SHA256:bsA1SKZxuEcEVHAy3gY1HUeM5ykRJl0U0kQHQn0hMg8
5 changed files with 69 additions and 20 deletions

2
.devcontainer/devcontainer.json Normal file → Executable file
View file

@ -57,7 +57,7 @@
"extensions": [ "extensions": [
"vadimcn.vscode-lldb", "vadimcn.vscode-lldb",
"serayuzgur.crates", "serayuzgur.crates",
"bungcip.better-toml", "tamasfe.even-better-toml",
"rust-lang.rust-analyzer", "rust-lang.rust-analyzer",
"mutantdino.resourcemonitor", "mutantdino.resourcemonitor",
"christian-kohler.path-intellisense", "christian-kohler.path-intellisense",

View file

@ -4,7 +4,7 @@ version = "0.1.0"
edition = "2021" edition = "2021"
[dependencies] [dependencies]
polars = { version = "0.28", features = [ polars = { version = "0.32", features = [
"lazy", "lazy",
"strings", "strings",
"parquet", "parquet",
@ -22,4 +22,5 @@ chrono = { version = "0.4", features = ["serde"] }
glob = { version = "0.3" } glob = { version = "0.3" }
strum_macros = "0.25" strum_macros = "0.25"
tower = { version = "0.4", features = ["limit", "buffer"] } tower = { version = "0.4", features = ["limit", "buffer"] }
tower-http = { version = "0.4", features = ["cors"] } tower-http = { version = "0.4", features = ["compression-zstd", "cors"] }
tower_governor = "0.1"

17
docker-compose.dev.yml Normal file
View file

@ -0,0 +1,17 @@
version: "3"
services:
ark-invest-api-rust:
image: ark-invest-api-rust
build:
context: .
args:
DOCKER_BUILDKIT: 1
container_name: ark-invest-api-rust
restart: unless-stopped
volumes:
- ./data:/ark-invest-api-rust/data
ports:
- "3000:3000"
volumes:
data:

View file

@ -2,11 +2,6 @@ version: "3"
services: services:
ark-invest-api-rust: ark-invest-api-rust:
image: ghcr.io/NexVeridian/ark-invest-api-rust:latest image: ghcr.io/NexVeridian/ark-invest-api-rust:latest
# image: ark-invest-api-rust
build:
context: .
args:
DOCKER_BUILDKIT: 1
container_name: ark-invest-api-rust container_name: ark-invest-api-rust
restart: unless-stopped restart: unless-stopped
volumes: volumes:

View file

@ -14,7 +14,13 @@ use axum::{
}; };
use std::{net::SocketAddr, time::Duration}; use std::{net::SocketAddr, time::Duration};
use tower::{buffer::BufferLayer, limit::RateLimitLayer, ServiceBuilder}; use tower::{buffer::BufferLayer, limit::RateLimitLayer, ServiceBuilder};
use tower_http::cors::{Any, CorsLayer}; use tower_governor::{
governor::GovernorConfigBuilder, key_extractor::SmartIpKeyExtractor, GovernorLayer,
};
use tower_http::{
compression::CompressionLayer,
cors::{Any, CorsLayer},
};
mod routes; mod routes;
@ -33,18 +39,40 @@ fn description_date(op: TransformOperation) -> TransformOperation {
#[tokio::main] #[tokio::main]
async fn main() { async fn main() {
let rate_limit = |req_per_sec: u64| { let error_handler = || {
ServiceBuilder::new() ServiceBuilder::new().layer(HandleErrorLayer::new(|err: BoxError| async move {
.layer(HandleErrorLayer::new(|err: BoxError| async move {
( (
StatusCode::INTERNAL_SERVER_ERROR, StatusCode::INTERNAL_SERVER_ERROR,
format!("Unhandled error: {}", err), format!("Unhandled error: {}", err),
) )
})) }))
};
let rate_limit_global = |req_per_sec: u64| {
ServiceBuilder::new()
.layer(error_handler())
.layer(BufferLayer::new(1024)) .layer(BufferLayer::new(1024))
.layer(RateLimitLayer::new(req_per_sec, Duration::from_secs(1))) .layer(RateLimitLayer::new(req_per_sec, Duration::from_secs(1)))
}; };
let rate_limit_ip = || {
let config = Box::new(
GovernorConfigBuilder::default()
.per_second(2)
.burst_size(10)
.use_headers()
.key_extractor(SmartIpKeyExtractor)
.finish()
.unwrap(),
);
ServiceBuilder::new()
.layer(error_handler())
.layer(GovernorLayer {
config: Box::leak(config),
})
};
let cors = || { let cors = || {
ServiceBuilder::new().layer( ServiceBuilder::new().layer(
CorsLayer::new() CorsLayer::new()
@ -62,8 +90,12 @@ async fn main() {
description_date(o) description_date(o)
}), }),
) )
.layer(rate_limit(5)) .layer(
rate_limit_global(500)
.layer(rate_limit_ip())
.layer(cors()) .layer(cors())
.layer(CompressionLayer::new().zstd(true)),
)
.api_route( .api_route(
"/ark_holdings", "/ark_holdings",
get_with(routes::ark_holdings, |mut o| { get_with(routes::ark_holdings, |mut o| {
@ -71,8 +103,12 @@ async fn main() {
description_date(o) description_date(o)
}), }),
) )
.layer(rate_limit(20)) .layer(
rate_limit_global(200)
.layer(rate_limit_ip())
.layer(cors()) .layer(cors())
.layer(CompressionLayer::new().zstd(true)),
)
.route("/api.json", get(serve_api)); .route("/api.json", get(serve_api));
let mut api = OpenApi { let mut api = OpenApi {