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

Tower #83

Draft
wants to merge 81 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
81 commits
Select commit Hold shift + click to select a range
87e08d0
feat(tower)!: implement tower integration and remove actix deps
singulared Jun 15, 2023
84d597a
feat(tower)!: wip implementation of tower integration
singulared Jun 19, 2023
f772f35
feat(tower)!: wip implementation of tower integration
singulared Jun 24, 2023
144385b
feat(tower)!: wip implementation of tower integration
singulared Jun 25, 2023
04674fe
Add predicates: Header + Path + Query
Jun 25, 2023
2dc6e1e
feat(tower): adds transformer functions
singulared Jul 2, 2023
a53e914
feat(tower): generic `CacheableHttpRequest`
singulared Jul 2, 2023
3b011d1
Merge branch 'tower' of github.com:hit-box/hitbox into tower
singulared Jul 2, 2023
68baeb2
feat(tower): add simple body request predicate
singulared Jul 3, 2023
55d100b
feat(tower): add trait `FromBytes` and generic implementations
singulared Jul 4, 2023
0470a19
feat(tower): implement all cache future states
singulared Jul 9, 2023
96e8125
feat!(tower): update axum example
singulared Jul 9, 2023
a1e7fd5
feat(tower)!: pass borrowed `CachedValue` into `CacheBackend::set`
singulared Jul 9, 2023
c4d0a08
feat(tower): don't clone upstream response in fsm
singulared Jul 9, 2023
00efaa3
Add Stretto backend
AndreyErmilov Jul 12, 2023
5f547b9
feat(tower): refactor predicates
singulared Jul 18, 2023
5d94f26
feat(tower)!: predicates refactoring
singulared Jul 19, 2023
9ef63e8
Stretto in-memory backend
AndreyErmilov Jul 29, 2023
9ff7d6c
feat(tower): update predicate params in `CacheFuture`
singulared Aug 8, 2023
364bcfd
feat(extractors)!: implement cache key generation and extractors
singulared Aug 8, 2023
9b4dffd
feat(extractors): add query extractor
AndreyErmilov Aug 11, 2023
0a27a34
feat(extractors): Fix hitbox_qs
AndreyErmilov Aug 13, 2023
ebdb03c
Merge branch 'tower' into in-memory-backend
AndreyErmilov Aug 13, 2023
7f32896
Merge pull request #85 from hit-box/in-memory-backend
AndreyErmilov Aug 13, 2023
2a22347
feat(config): Add dummy backend
AndreyErmilov Aug 13, 2023
8a135c2
feat(config): Add predicates to layer
AndreyErmilov Aug 13, 2023
77a64bd
feat(config): Add endpoint config
AndreyErmilov Aug 13, 2023
ee60cc7
feat(config): Intermediate result
AndreyErmilov Aug 14, 2023
af78e25
docs(fsm): add fsm state diagram
singulared Aug 14, 2023
52c156e
feat(config): Add extractors
AndreyErmilov Aug 15, 2023
99d7f7f
feat(config)!: refactor Cache configuration interface
singulared Aug 16, 2023
60d50c9
Merge pull request #86 from hit-box/tower-config
singulared Aug 16, 2023
17c9fae
feat(core)!: add hitbox-core sub-crate
singulared Aug 17, 2023
054a6db
fix(fmt): cargo fmt
singulared Aug 17, 2023
296b185
feat(config): Add missing response predicate + extractor
AndreyErmilov Aug 18, 2023
494ecb6
feat(config): Add configuration for setting up cache policy
AndreyErmilov Aug 20, 2023
c888088
feat(config): small fix
AndreyErmilov Aug 20, 2023
7e1b211
feat(config): remove useless ServiceBuilder from axum example
AndreyErmilov Aug 20, 2023
46d85ce
feat(backend)!: use `CacheKey` in `CacheBackend` trait
singulared Aug 20, 2023
8948e82
feat(key-generation): add simple `UrlEncodedSerializer` for `CacheKey`
singulared Aug 20, 2023
44b371a
feat(key-generation): rename `UrlEncodedSerializer` to `UrlEncodedKey…
singulared Aug 20, 2023
4a42a13
fix(examples): fix tower example
singulared Aug 20, 2023
f742b04
feat(predicates): split predicates into request and response
singulared Aug 20, 2023
dbb5229
feat(config): Add serialize & deserializer to EndpointConfig
AndreyErmilov Aug 22, 2023
dbb6c04
feat(config): Move policy field into endpoint config
AndreyErmilov Aug 26, 2023
a096a0c
refactor(config): Restructure hitbox-tower config
AndreyErmilov Aug 27, 2023
1665df9
refactor(config): Add trait Configurable
AndreyErmilov Aug 27, 2023
cd874a9
chore(cargo): use workspace resoilver 2
singulared Aug 27, 2023
07d8482
refactor(config): layer uses generic Configurable
AndreyErmilov Aug 27, 2023
a7a2617
Merge pull request #92 from hit-box/tower-trait-configurable
AndreyErmilov Aug 27, 2023
2878240
fix(examples): disable broken examples
singulared Aug 27, 2023
225bffd
chore: increase MSRV to 1.63
singulared Aug 27, 2023
d7f1d0f
chore: increase MSRV to 1.64
singulared Aug 27, 2023
391a86d
chore: increase MSRV to 1.70
singulared Aug 27, 2023
40a376a
refactor(config): Rename Configurable to CacheConfig
AndreyErmilov Aug 27, 2023
0ec39df
feat(hyper-error-handling): adds handling for hyper HTTP errors
singulared Aug 26, 2024
0961887
tarantool: add crate structure
lowitea Jul 9, 2023
8da4099
tarantool: add first dirty implementation
lowitea Jul 19, 2023
3605897
tarantool: add integration test for start
lowitea Jul 27, 2023
3f611e6
tarantool: add test for set function
lowitea Aug 6, 2023
8154f60
tarantool: add rest tests
lowitea Aug 9, 2023
5c17073
tarantool: fix after rebase
lowitea Aug 13, 2023
7c224be
tarantool: move init tarantool to init
lowitea Aug 13, 2023
21c4fe4
tarantool: improve tests
lowitea Aug 13, 2023
1f9ee6c
tarantool: add expiration test
lowitea Aug 13, 2023
e129e99
tarantool: fix missing key delete
lowitea Aug 13, 2023
a899e8f
tarantool: improve tests
lowitea Aug 13, 2023
b96d46d
tarantool: move cache entry structure to backend
lowitea Aug 14, 2023
fef1c4a
tarantool: improve backend code
lowitea Aug 14, 2023
ce54ccb
tarantool: mark completed tasks
lowitea Aug 14, 2023
834c46e
tarantool: add docs
lowitea Aug 14, 2023
43df7ec
tarantool: move init script to separate file
lowitea Aug 15, 2023
45037c0
tarantool: add interface for tarantool
lowitea Aug 20, 2023
78b6049
tarantool: remove extra serialization
lowitea Aug 22, 2023
23511e2
tarantool: doc hidden for CacheEntry
lowitea Aug 25, 2023
c3d938d
tarantool: change derive builder to typed builder
lowitea Aug 25, 2023
93c28d6
tarantool: change index type to hash
lowitea Aug 25, 2023
9d2295c
tarantool: rename StartedTarantool to TarantoolContainer
lowitea Aug 25, 2023
0d1e8aa
tarantool: add index for cleansing fiber
lowitea Aug 31, 2024
71850fe
tarantool: fix compatibility with new interface of traits
lowitea Sep 1, 2024
978d264
Merge pull request #82 from hit-box/tarantool
singulared Sep 11, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
rust: [1.60.0, stable]
rust: [1.70.0, stable]
steps:
- uses: actions/checkout@v3
- uses: actions-rs/toolchain@v1
Expand All @@ -31,7 +31,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
rust: [1.60.0, stable, beta]
rust: [1.70.0, stable, beta]
redis-version: [6]
steps:
- uses: actions/checkout@v3
Expand Down
7 changes: 4 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
[workspace]
resolver = "2"

members = [
"hitbox",
"hitbox-tokio",
"hitbox-actix",
"hitbox-backend",
"hitbox-derive",
"hitbox-core",
"hitbox-redis",
"hitbox-stretto",
"hitbox-tower",
"hitbox-tarantool",
"examples",
]
64 changes: 64 additions & 0 deletions documentation/fsm.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# Main cache flow diagram
```mermaid
stateDiagram-v2
classDef Implemented fill:lightgreen,color:black,font-weight:bold,stroke-width:2px,stroke:green
classDef Unimplemented fill:red,color:black,font-weight:bold,stroke-width:2px,stroke:red
class Initial Implemented
class if_cache_enabled Unimplemented
class CheckRequestCachePolicy Implemented
class match_request_cache_policy Implemented
class PollCache Implemented
class check_backend_result Implemented
class CheckCacheState Implemented
class check_cache_state Implemented
class Response Implemented
class PollUpstream Implemented
class UpstreamPolled Implemented
class CheckResponseCachePolicy Implemented
class UpdateCache Implemented
class AcquireCacheLock Unimplemented

state if_cache_enabled <<choice>>
[*] --> Initial
Initial --> if_cache_enabled
if_cache_enabled --> CheckRequestCachePolicy: config.enabled = true
if_cache_enabled --> PollUpstream: config.enabled = false

state match_request_cache_policy <<choice>>
CheckRequestCachePolicy --> match_request_cache_policy
match_request_cache_policy --> PollCache: request policy = Cacheable
match_request_cache_policy --> PollUpstream: request policy = NonCacheable

state check_backend_result <<choice>>
PollCache --> check_backend_result
check_backend_result --> CheckCacheState: backend_result = Some
check_backend_result --> PollUpstream: backend_result = None

state check_cache_state <<choice>>
state check_stale_config <<choice>>
CheckCacheState --> check_cache_state
check_cache_state --> check_stale_config: cache_state = Stale
check_cache_state --> Response: cache_state = Actual

state check_lock_config <<choice>>
check_stale_config --> check_lock_config: config.stale = enabled
check_stale_config --> Response: config.stale = disable

check_lock_config --> AcquireCacheLock: config.lock = enabled
check_lock_config --> PollUpstream: config.lock = disabled
AcquireCacheLock --> PollUpstream

PollUpstream --> UpstreamPolled
state check_cache_key <<choice>>
UpstreamPolled --> check_cache_key
check_cache_key --> Response: cache_key = None
check_cache_key --> CheckResponseCachePolicy: cache_key = Some

state match_response_cache_policy <<choice>>
CheckResponseCachePolicy --> match_response_cache_policy
match_response_cache_policy --> Response: response policy = NonCacheable
match_response_cache_policy --> UpdateCache: response policy = Cacheable

UpdateCache --> Response
Response --> [*]
```
36 changes: 21 additions & 15 deletions examples/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,31 +3,37 @@ name = "hitbox-examples"
version = "0.0.0"
publish = false
edition = "2021"
autoexamples = false

[features]
default = []

[dev-dependencies]
hitbox = { path = "../hitbox", features = ["derive", "metrics"] }
hitbox-actix = { path = "../hitbox-actix", features = ["redis"]}
hitbox = { path = "../hitbox", features = ["metrics"] }
hitbox-backend = { path = "../hitbox-backend" }
hitbox-tower = { path = "../hitbox-tower" }
hitbox-redis = { path = "../hitbox-redis" }
hitbox-stretto = { path = "../hitbox-stretto" }
actix = "0.13"
axum = "0.6"
log = "0.4"
actix-rt = "2"
serde_json = "1"
serde_qs = { version = "0.10" }
serde = { version = "1", features = ["derive"] }
chrono = { version = "0.4", features = ["serde"] }
thiserror = "1"
prometheus = { version = "0.13" }
env_logger = "0.9"
actix_derive = "0.6"
actix-web = "4.0"
tracing = "0.1"
tracing-subscriber = "0.3"
metrics-exporter-prometheus = "0.11"

env_logger = "0.10"
serde_json = "1"
hyper = { version = "0.14", features = ["full"] }
tokio = { version = "1", features = ["full"] }
tower = { version = "0.4", features = ["full"] }
tower-http = { version = "0.3", features = ["full"] }
tower-http = { version = "0.4", features = ["full"] }
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
tracing = { version = "0.1" }
http = "0.2"
lazy_static = "1"

[[example]]
name = "axum"
path = "examples/axum.rs"

[[example]]
name = "tower"
path = "examples/tower.rs"
4 changes: 1 addition & 3 deletions examples/examples/async_backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,4 @@ async fn main() -> Result<(), CacheError> {
Ok(())
}*/

fn main() {

}
fn main() {}
87 changes: 87 additions & 0 deletions examples/examples/axum.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
use axum::{extract::Path, routing::get, Json, Router};
use hitbox_tower::{
configuration::extractor,
configuration::predicate::{request, response},
Method, StatusCode,
};

use hitbox_redis::RedisBackend;
use hitbox_tower::{Cache, EndpointConfig};

async fn handler_result(Path(_name): Path<String>) -> Result<String, StatusCode> {
//dbg!("axum::handler_result");
// Ok(format!("Hello, {name}"))
Err(StatusCode::INTERNAL_SERVER_ERROR)
}

async fn handler() -> String {
//dbg!("axum::handler");
"root".to_string()
}

#[derive(serde::Serialize)]
struct Greet {
name: String,
answer: u32,
}

async fn handler_json() -> Json<Greet> {
//dbg!("axum::handler");
Json(Greet {
name: "root".to_owned(),
answer: 42,
})
}

#[tokio::main]
async fn main() {
let subscriber = tracing_subscriber::fmt()
.pretty()
.with_env_filter("debug,hitbox=trace")
.finish();
tracing::subscriber::set_global_default(subscriber).unwrap();

let redis_backend = RedisBackend::new().unwrap();
let inmemory_backend = hitbox_stretto::StrettoBackend::builder(10)
.finalize()
.unwrap();

let json_config = EndpointConfig::builder()
.request(
request::method(Method::GET)
.query("cache", "true")
.query("x-cache", "true")
.path("/{path}*"),
)
.response(response::status_code(StatusCode::OK))
.cache_key(extractor::method().query("cache").path("/{path}*"))
.build();

let health_config = EndpointConfig::builder()
.request(request::path("/health").method(Method::GET))
.disable()
.build();

let json_cache = Cache::builder()
.backend(redis_backend)
.config(json_config)
.build();

let health_check = Cache::builder()
.backend(inmemory_backend) // FIX: it should work withod backend
.config(health_config)
.build();

let app = Router::new()
.route("/greet/:name/", get(handler_result))
.route("/", get(handler))
.route("/json/", get(handler_json))
.route("/health", get(handler).layer(health_check))
.layer(json_cache);

// run it with hyper on localhost:3000
axum::Server::bind(&"0.0.0.0:3000".parse().unwrap())
.serve(app.into_make_service())
.await
.unwrap();
}
4 changes: 1 addition & 3 deletions examples/examples/cacheable_response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,4 @@ async fn main() -> Result<(), CacheError> {
Ok(())
}*/

fn main() {

}
fn main() {}
4 changes: 1 addition & 3 deletions examples/examples/sync_backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,4 @@ async fn main() -> Result<(), CacheError> {
Ok(())
}*/

fn main() {

}
fn main() {}
25 changes: 19 additions & 6 deletions examples/examples/tower.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,31 @@
use std::{convert::Infallible, net::SocketAddr};
use hitbox_redis::RedisBackend;
use hitbox_stretto::StrettoBackend;
use hitbox_tower::Cache;
use hyper::{Body, Server};
use std::net::SocketAddr;

use http::{Method, Request, Response};
use tower::make::Shared;
use http::{Request, Response};

async fn handle(_: Request<Body>) -> Result<Response<Body>, Infallible> {
Ok(Response::new("Hello, World!".into()))
async fn handle(_: Request<Body>) -> http::Result<Response<Body>> {
// Ok(Response::new("Hello, World!".into()))
Err(http::Error::from(Method::from_bytes(&[0x01]).unwrap_err()))
}

#[tokio::main]
async fn main() {
let subscriber = tracing_subscriber::fmt()
.pretty()
.with_env_filter("debug,hitbox=trace")
.finish();
tracing::subscriber::set_global_default(subscriber).unwrap();

let inmemory = StrettoBackend::builder(10_000_000).finalize().unwrap();
let redis = RedisBackend::builder().build().unwrap();

let service = tower::ServiceBuilder::new()
.layer(tower_http::trace::TraceLayer::new_for_http())
// .layer(Cache::builder().backend(inmemory).build())
.layer(Cache::builder().backend(redis).build())
.service_fn(handle);

let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
Expand All @@ -20,4 +34,3 @@ async fn main() {
.await
.expect("server error");
}

11 changes: 0 additions & 11 deletions hitbox-actix/CHANGELOG.md

This file was deleted.

33 changes: 0 additions & 33 deletions hitbox-actix/Cargo.toml

This file was deleted.

Loading
Loading