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

Update Limitador to Tokio 1 async reactor #54

Merged
merged 20 commits into from
Jan 24, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
d26ccf9
Cargo.toml: include missing package keywords
unleashed Dec 22, 2021
de1cc5b
misc: deny clippy/cargo warnings
unleashed Dec 22, 2021
ff4e668
misc: Cargo.toml formatting
unleashed Dec 22, 2021
9e92f45
misc: use semver specs in Cargo.toml
unleashed Dec 22, 2021
945838b
limitador-server: update tonic to 0.6
unleashed Dec 22, 2021
c8fd2f4
limitador-server/envoy_rls/protobufs: regenerate with newer tonic
unleashed Dec 22, 2021
1679391
limitador-server: update env_logger to 0.9
unleashed Dec 22, 2021
e7d6d78
limitador: update prometheus to 0.13
unleashed Dec 22, 2021
940b2cc
limitador: update dev dependency rand to 0.8
unleashed Dec 22, 2021
6d4cbba
limitador-server: update paperclip to 0.6
unleashed Dec 22, 2021
af5b74f
limitador-server: update actix_rt to version 2
unleashed Dec 22, 2021
87efbe5
limitador/Cargo.toml: depend on new infinispan release and drop old r…
unleashed Dec 24, 2021
596fa98
limitador: migrate delay_for to sleep in Tokio 1
unleashed Dec 24, 2021
7b34e1b
limitador: upgrade the redis crate dependency to 0.21
unleashed Dec 24, 2021
dffaa25
limitador/storage/redis: fix api breakages in 0.21
unleashed Dec 24, 2021
3d88929
limitador-server: upgrade to actix-web 4 with a suitable paperclip dep
unleashed Dec 24, 2021
0d75350
server/http_api/server: replace actix-web deprecated fn with new one
unleashed Jan 20, 2022
c61a250
Dockerfile: bump Rust to 1.58 in build image
unleashed Jan 20, 2022
5636808
Cargo.lock: round of updates
unleashed Jan 21, 2022
c2d69a7
server/main: remove unneeded to_string call
unleashed Jan 21, 2022
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
1,846 changes: 486 additions & 1,360 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# Build Stage
# ------------------------------------------------------------------------------

FROM rust:1.52 as limitador-build
FROM rust:1.58 as limitador-build

RUN apt-get update \
&& apt-get install musl-tools -y
Expand Down
31 changes: 19 additions & 12 deletions limitador-server/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,32 @@ name = "limitador-server"
version = "0.4.0"
authors = ["David Ortiz <z.david.ortiz@gmail.com>"]
license = "Apache-2.0"
keywords = ["rate-limiting", "rate", "limiter", "envoy", "rls"]
categories = ["web-programming"]
description = "Rate limiting service that integrates with Envoy's RLS protocol"
homepage = "https://github.com/kuadrant/limitador"
repository = "https://github.com/kuadrant/limitador"
documentation = "https://docs.rs/limitador"
readme = "README.md"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
limitador = { path = "../limitador", features = ['infinispan_storage'] }
tokio = { version = "0.2", features = ["full"] }
thiserror = "1.0"
tonic = "0.3"
prost = "0.6"
prost-types = "0.6"
tokio = { version = "1", features = ["full"] }
thiserror = "1"
tonic = "0.6"
prost = "0.9"
prost-types = "0.9"
serde_yaml = "0.8"
log = "0.4"
env_logger = "0.8"
url = "2.2"
actix-web = "3"
actix-rt = "1"
paperclip = { version = "0.5", features = ["actix"] }
serde = { version = "1.0", features = ["derive"] }
env_logger = "0.9"
url = "2"
actix-web = "= 4.0.0-beta.20"
actix-rt = "2"
paperclip = { git = "https://github.com/sfisol/paperclip", rev = "99db92949e95287fbeb8f3ea844291f1810cccee", features = ["actix"] }
serde = { version = "1", features = ["derive"] }

[build-dependencies]
tonic-build = "0.2"
tonic-build = "0.6"
161 changes: 85 additions & 76 deletions limitador-server/src/envoy_rls/protobufs/envoy.config.core.v3.rs

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -45,16 +45,17 @@
pub struct RateLimitDescriptor {
/// Descriptor entries.
#[prost(message, repeated, tag = "1")]
pub entries: ::std::vec::Vec<rate_limit_descriptor::Entry>,
pub entries: ::prost::alloc::vec::Vec<rate_limit_descriptor::Entry>,
}
/// Nested message and enum types in `RateLimitDescriptor`.
pub mod rate_limit_descriptor {
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct Entry {
/// Descriptor key.
#[prost(string, tag = "1")]
pub key: std::string::String,
pub key: ::prost::alloc::string::String,
/// Descriptor value.
#[prost(string, tag = "2")]
pub value: std::string::String,
pub value: ::prost::alloc::string::String,
}
}
3 changes: 2 additions & 1 deletion limitador-server/src/envoy_rls/protobufs/envoy.r#type.v3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ pub struct FractionalPercent {
#[prost(enumeration = "fractional_percent::DenominatorType", tag = "2")]
pub denominator: i32,
}
/// Nested message and enum types in `FractionalPercent`.
pub mod fractional_percent {
/// Fraction percentages support several fixed denominator values.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
Expand All @@ -43,7 +44,7 @@ pub mod fractional_percent {
}
// [#protodoc-title: Semantic Version]

/// Envoy uses SemVer (https://semver.org/). Major/minor versions indicate
/// Envoy uses SemVer (<https://semver.org/>). Major/minor versions indicate
/// expected behaviors and APIs, the patch version field is used only
/// for security fixes and can be generally ignored.
#[derive(Clone, PartialEq, ::prost::Message)]
Expand Down
121 changes: 75 additions & 46 deletions limitador-server/src/envoy_rls/protobufs/envoy.service.ratelimit.v3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ pub struct RateLimitRequest {
/// All rate limit requests must specify a domain. This enables the configuration to be per
/// application without fear of overlap. E.g., "envoy".
#[prost(string, tag = "1")]
pub domain: std::string::String,
pub domain: ::prost::alloc::string::String,
/// All rate limit requests must specify at least one RateLimitDescriptor. Each descriptor is
/// processed by the service (see below). If any of the descriptors are over limit, the entire
/// request is considered to be over limit.
#[prost(message, repeated, tag = "2")]
pub descriptors: ::std::vec::Vec<
pub descriptors: ::prost::alloc::vec::Vec<
super::super::super::extensions::common::ratelimit::v3::RateLimitDescriptor,
>,
/// Rate limit requests can optionally specify the number of hits a request adds to the matched
Expand All @@ -34,29 +34,32 @@ pub struct RateLimitResponse {
/// in the RateLimitRequest. This can be used by the caller to determine which individual
/// descriptors failed and/or what the currently configured limits are for all of them.
#[prost(message, repeated, tag = "2")]
pub statuses: ::std::vec::Vec<rate_limit_response::DescriptorStatus>,
pub statuses: ::prost::alloc::vec::Vec<rate_limit_response::DescriptorStatus>,
/// A list of headers to add to the response
#[prost(message, repeated, tag = "3")]
pub response_headers_to_add:
::std::vec::Vec<super::super::super::config::core::v3::HeaderValue>,
::prost::alloc::vec::Vec<super::super::super::config::core::v3::HeaderValue>,
/// A list of headers to add to the request when forwarded
#[prost(message, repeated, tag = "4")]
pub request_headers_to_add: ::std::vec::Vec<super::super::super::config::core::v3::HeaderValue>,
pub request_headers_to_add:
::prost::alloc::vec::Vec<super::super::super::config::core::v3::HeaderValue>,
}
/// Nested message and enum types in `RateLimitResponse`.
pub mod rate_limit_response {
/// Defines an actual rate limit in terms of requests per unit of time and the unit itself.
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct RateLimit {
/// A name or description of this limit.
#[prost(string, tag = "3")]
pub name: std::string::String,
pub name: ::prost::alloc::string::String,
/// The number of requests per unit of time.
#[prost(uint32, tag = "1")]
pub requests_per_unit: u32,
/// The unit of time.
#[prost(enumeration = "rate_limit::Unit", tag = "2")]
pub unit: i32,
}
/// Nested message and enum types in `RateLimit`.
pub mod rate_limit {
#[derive(
Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration,
Expand All @@ -82,7 +85,7 @@ pub mod rate_limit_response {
pub code: i32,
/// The current limit as configured by the server. Useful for debugging, etc.
#[prost(message, optional, tag = "2")]
pub current_limit: ::std::option::Option<RateLimit>,
pub current_limit: ::core::option::Option<RateLimit>,
/// The limit remaining in the current time unit.
#[prost(uint32, tag = "3")]
pub limit_remaining: u32,
Expand All @@ -100,8 +103,9 @@ pub mod rate_limit_response {
}
#[doc = r" Generated client implementations."]
pub mod rate_limit_service_client {
#![allow(unused_variables, dead_code, missing_docs)]
#![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)]
use tonic::codegen::*;
#[derive(Debug, Clone)]
pub struct RateLimitServiceClient<T> {
inner: tonic::client::Grpc<T>,
}
Expand All @@ -119,17 +123,43 @@ pub mod rate_limit_service_client {
impl<T> RateLimitServiceClient<T>
where
T: tonic::client::GrpcService<tonic::body::BoxBody>,
T::ResponseBody: Body + HttpBody + Send + 'static,
T::ResponseBody: Body + Send + 'static,
T::Error: Into<StdError>,
<T::ResponseBody as HttpBody>::Error: Into<StdError> + Send,
<T::ResponseBody as Body>::Error: Into<StdError> + Send,
{
pub fn new(inner: T) -> Self {
let inner = tonic::client::Grpc::new(inner);
Self { inner }
}
pub fn with_interceptor(inner: T, interceptor: impl Into<tonic::Interceptor>) -> Self {
let inner = tonic::client::Grpc::with_interceptor(inner, interceptor);
Self { inner }
pub fn with_interceptor<F>(
inner: T,
interceptor: F,
) -> RateLimitServiceClient<InterceptedService<T, F>>
where
F: tonic::service::Interceptor,
T: tonic::codegen::Service<
http::Request<tonic::body::BoxBody>,
Response = http::Response<
<T as tonic::client::GrpcService<tonic::body::BoxBody>>::ResponseBody,
>,
>,
<T as tonic::codegen::Service<http::Request<tonic::body::BoxBody>>>::Error:
Into<StdError> + Send + Sync,
{
RateLimitServiceClient::new(InterceptedService::new(inner, interceptor))
}
#[doc = r" Compress requests with `gzip`."]
#[doc = r""]
#[doc = r" This requires the server to support it otherwise it might respond with an"]
#[doc = r" error."]
pub fn send_gzip(mut self) -> Self {
self.inner = self.inner.send_gzip();
self
}
#[doc = r" Enable decompressing responses with `gzip`."]
pub fn accept_gzip(mut self) -> Self {
self.inner = self.inner.accept_gzip();
self
}
#[doc = " Determine whether rate limiting should take place."]
pub async fn should_rate_limit(
Expand All @@ -149,22 +179,10 @@ pub mod rate_limit_service_client {
self.inner.unary(request.into_request(), path, codec).await
}
}
impl<T: Clone> Clone for RateLimitServiceClient<T> {
fn clone(&self) -> Self {
Self {
inner: self.inner.clone(),
}
}
}
impl<T> std::fmt::Debug for RateLimitServiceClient<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "RateLimitServiceClient {{ ... }}")
}
}
}
#[doc = r" Generated server implementations."]
pub mod rate_limit_service_server {
#![allow(unused_variables, dead_code, missing_docs)]
#![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)]
use tonic::codegen::*;
#[doc = "Generated trait containing gRPC methods that should be implemented for use with RateLimitServiceServer."]
#[async_trait]
Expand All @@ -176,27 +194,33 @@ pub mod rate_limit_service_server {
) -> Result<tonic::Response<super::RateLimitResponse>, tonic::Status>;
}
#[derive(Debug)]
#[doc(hidden)]
pub struct RateLimitServiceServer<T: RateLimitService> {
inner: _Inner<T>,
accept_compression_encodings: (),
send_compression_encodings: (),
}
struct _Inner<T>(Arc<T>, Option<tonic::Interceptor>);
struct _Inner<T>(Arc<T>);
impl<T: RateLimitService> RateLimitServiceServer<T> {
pub fn new(inner: T) -> Self {
let inner = Arc::new(inner);
let inner = _Inner(inner, None);
Self { inner }
let inner = _Inner(inner);
Self {
inner,
accept_compression_encodings: Default::default(),
send_compression_encodings: Default::default(),
}
}
pub fn with_interceptor(inner: T, interceptor: impl Into<tonic::Interceptor>) -> Self {
let inner = Arc::new(inner);
let inner = _Inner(inner, Some(interceptor.into()));
Self { inner }
pub fn with_interceptor<F>(inner: T, interceptor: F) -> InterceptedService<Self, F>
where
F: tonic::service::Interceptor,
{
InterceptedService::new(Self::new(inner), interceptor)
}
}
impl<T, B> Service<http::Request<B>> for RateLimitServiceServer<T>
impl<T, B> tonic::codegen::Service<http::Request<B>> for RateLimitServiceServer<T>
where
T: RateLimitService,
B: HttpBody + Send + Sync + 'static,
B: Body + Send + 'static,
B::Error: Into<StdError> + Send + 'static,
{
type Response = http::Response<tonic::body::BoxBody>;
Expand All @@ -221,21 +245,21 @@ pub mod rate_limit_service_server {
request: tonic::Request<super::RateLimitRequest>,
) -> Self::Future {
let inner = self.0.clone();
let fut = async move { inner.should_rate_limit(request).await };
let fut = async move { (*inner).should_rate_limit(request).await };
Box::pin(fut)
}
}
let accept_compression_encodings = self.accept_compression_encodings;
let send_compression_encodings = self.send_compression_encodings;
let inner = self.inner.clone();
let fut = async move {
let interceptor = inner.1.clone();
let inner = inner.0;
let method = ShouldRateLimitSvc(inner);
let codec = tonic::codec::ProstCodec::default();
let mut grpc = if let Some(interceptor) = interceptor {
tonic::server::Grpc::with_interceptor(codec, interceptor)
} else {
tonic::server::Grpc::new(codec)
};
let mut grpc = tonic::server::Grpc::new(codec).apply_compression_config(
accept_compression_encodings,
send_compression_encodings,
);
let res = grpc.unary(method, req).await;
Ok(res)
};
Expand All @@ -245,7 +269,8 @@ pub mod rate_limit_service_server {
Ok(http::Response::builder()
.status(200)
.header("grpc-status", "12")
.body(tonic::body::BoxBody::empty())
.header("content-type", "application/grpc")
.body(empty_body())
.unwrap())
}),
}
Expand All @@ -254,12 +279,16 @@ pub mod rate_limit_service_server {
impl<T: RateLimitService> Clone for RateLimitServiceServer<T> {
fn clone(&self) -> Self {
let inner = self.inner.clone();
Self { inner }
Self {
inner,
accept_compression_encodings: self.accept_compression_encodings,
send_compression_encodings: self.send_compression_encodings,
}
}
}
impl<T: RateLimitService> Clone for _Inner<T> {
fn clone(&self) -> Self {
Self(self.0.clone(), self.1.clone())
Self(self.0.clone())
}
}
impl<T: std::fmt::Debug> std::fmt::Debug for _Inner<T> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,5 @@ pub struct VersioningAnnotation {
/// udpa.foo.v3alpha.Foo and it was previously udpa.bar.v2.Bar. This
/// information is consumed by UDPA via proto descriptors.
#[prost(string, tag = "1")]
pub previous_message_type: std::string::String,
pub previous_message_type: ::prost::alloc::string::String,
}
Loading