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

feat(plugin):router_limits plugin added #6598

Merged
merged 115 commits into from
Jan 29, 2025
Merged
Show file tree
Hide file tree
Changes from 112 commits
Commits
Show all changes
115 commits
Select commit Hold shift + click to select a range
bef5367
First draft of a backpressure enabled pipeline
garypen Dec 18, 2024
6d80932
Obey the linter...
garypen Dec 18, 2024
7491e1e
Merge branch 'next' into garypen/next-backpressure
garypen Dec 18, 2024
718a870
Merge branch 'next' into garypen/next-backpressure
garypen Jan 6, 2025
4c93a96
Merge branch 'next' into garypen/next-backpressure
garypen Jan 7, 2025
716f7e5
Fix the rhai integration test
garypen Jan 7, 2025
8b7653b
fix lint complaint
garypen Jan 7, 2025
746d2c0
Add the new rhai testng config file
garypen Jan 7, 2025
330f969
temporarily comment out one test
garypen Jan 8, 2025
1b724d5
still experimenting to see how far away this approach is
garypen Jan 8, 2025
f932806
Move limits to traffic shaping
Jan 9, 2025
3b8ed61
Rename http_server to router
Jan 9, 2025
81faed0
Fix formatting errors reported by lint
garypen Jan 9, 2025
fc2e822
Fix the rate limiting test so that it works with new rate limiting
garypen Jan 9, 2025
3155440
Rename some stuff to minimise change from 1.x
garypen Jan 10, 2025
9bd0386
Try to restore the existing behaviour for reporting errors
garypen Jan 10, 2025
5627dce
Clean up some of the failing tests
garypen Jan 10, 2025
7432306
Fix lint complaints
garypen Jan 10, 2025
d05619f
Remove 1/2 implemented little loadshedder
garypen Jan 13, 2025
69e36f1
Merge branch 'next' into garypen/next-backpressure
garypen Jan 13, 2025
b85ca4f
POC: Make supergraph creator clone a BoxCloneService
garypen Jan 13, 2025
d5718f2
Fix AsyncCheckpoint and update tests for correct behaviour
garypen Jan 14, 2025
5c72744
Fix the xtask lint complaints
garypen Jan 14, 2025
a8a8950
POC: Make supergraph creator clone a BoxCloneService (#6540)
garypen Jan 14, 2025
21dee20
Modify subgraph rate-limiting test to pass for now
garypen Jan 14, 2025
00c1689
Merge branch 'next' into garypen/next-backpressure
garypen Jan 14, 2025
6c239aa
Small tidying up to use `buffered`
garypen Jan 15, 2025
f1cd40a
Document tower layers in router and supergraph services (#6549)
goto-bus-stop Jan 16, 2025
6788915
List the plugin tower layers
goto-bus-stop Jan 16, 2025
949ea23
Enforce backpressure between the router and qp services
garypen Jan 16, 2025
9511057
traffic_shaping: remove subgraph_service_internal method
IvanGoncharov Jan 16, 2025
e573024
Merge branch 'garypen/next-backpressure' into i1g/next-traffic_shaping
garypen Jan 17, 2025
f2303d6
traffic_shaping: remove subgraph_service_internal method (#6565)
garypen Jan 17, 2025
0c3b6b0
Fix the batching test snapshots
garypen Jan 17, 2025
98391f7
Bring subgraph rate-limiting to life
garypen Jan 17, 2025
fadae7b
Fix remaining broken tests
garypen Jan 18, 2025
83fd57c
xtask lint
garypen Jan 18, 2025
6caaa56
Fix mock expectations in affected examples tests
garypen Jan 20, 2025
ecf3aa9
Remove OneShotAsyncCheckpoint and associated functionality
garypen Jan 20, 2025
2f5014f
Revert change to axum_http_server_factory.rs
garypen Jan 20, 2025
77b2a59
Revert earlier changes to body limit layers and re-enable test
garypen Jan 20, 2025
3ffe632
A compromise solution for Body Limits
garypen Jan 20, 2025
11d19b2
Merge branch 'next' into garypen/next-backpressure
garypen Jan 20, 2025
ee3bd5a
Merge branch 'dev' into garypen/next-backpressure
garypen Jan 21, 2025
26364f6
Prepare PR for review.
garypen Jan 21, 2025
034686f
Merge branch 'dev' into garypen/next-backpressure
garypen Jan 21, 2025
57e8531
Add a helpful commit to explain the Mutex on make()
garypen Jan 21, 2025
d2156ed
add a changeset
garypen Jan 21, 2025
aac1492
Merge branch 'dev' into garypen/next-backpressure
garypen Jan 21, 2025
2107729
Fix some readying issues in tests and deduplication
garypen Jan 21, 2025
0bddcde
Found another inner service not following tower advice
garypen Jan 23, 2025
2b3bed2
Make subgraph_name mandatory on Request and Response
garypen Jan 23, 2025
f6525a8
Merge branch 'dev' into garypen/next-backpressure
garypen Jan 23, 2025
f08f21d
xtask lint
garypen Jan 23, 2025
339c502
Remove the comment because the name is no longer Option
garypen Jan 23, 2025
f3944d1
Code review comments.
garypen Jan 24, 2025
3b88d45
Spotted this dbg! in code review and should remove it
garypen Jan 24, 2025
017b0f1
Fix mistakes made during code review changes.
garypen Jan 24, 2025
9b75423
Replace our use of Mutex with a Buffer
garypen Jan 25, 2025
ddad68d
Add to the migration guide and the router documentation.
garypen Jan 27, 2025
c629fca
Merge branch 'dev' into garypen/next-backpressure
garypen Jan 27, 2025
b2c236f
Remember the name of the concurrency limit
garypen Jan 27, 2025
f5d3bdb
Fix the body limit layer.
Jan 27, 2025
95e22d8
Add a link to the appropriate PR for the migration changes
garypen Jan 27, 2025
f748a93
wrap up `mock_subgraph_service_withf_panics_should_be_reported_as_ser…
goto-bus-stop Jan 27, 2025
49fd09b
Fixup limits plugin tests
Jan 27, 2025
8ea3123
Fixup telemetry tests
Jan 27, 2025
149f7af
feat(plugins): `RouterLimits` into plugin ecosystem
aaronArinder Jan 16, 2025
ab6fbb2
gourd
aaronArinder Jan 21, 2025
571ef7d
gourd
aaronArinder Jan 21, 2025
e046d3e
gourd
aaronArinder Jan 21, 2025
ff4333e
gourd
aaronArinder Jan 21, 2025
39177af
gourd
aaronArinder Jan 21, 2025
14a2975
gourd
aaronArinder Jan 21, 2025
27d57c8
gourd
aaronArinder Jan 21, 2025
75b698b
gourd
aaronArinder Jan 21, 2025
2ea13fa
gourd
aaronArinder Jan 21, 2025
88779ab
gourd
aaronArinder Jan 21, 2025
50361fc
gourd
aaronArinder Jan 21, 2025
c7a8b8f
gourd
aaronArinder Jan 21, 2025
c4edc0c
gourd
aaronArinder Jan 21, 2025
15b1efd
gourd
aaronArinder Jan 21, 2025
87d70c2
gourd
aaronArinder Jan 21, 2025
a0c6cfe
gourd
aaronArinder Jan 21, 2025
504a903
gourd
aaronArinder Jan 21, 2025
6e7449a
gourd
aaronArinder Jan 21, 2025
f8a5e98
gourd
aaronArinder Jan 22, 2025
a0e34e3
Improve PluginTestHarness for multi call (#6623)
BrynCooke Jan 23, 2025
4acce20
gourd
aaronArinder Jan 23, 2025
b9df9de
gourd
aaronArinder Jan 23, 2025
08f5deb
gourd
aaronArinder Jan 23, 2025
570de5f
gourd
aaronArinder Jan 23, 2025
1dfcbea
gourd
aaronArinder Jan 24, 2025
9104cce
gourd
aaronArinder Jan 27, 2025
910af10
gourd
aaronArinder Jan 27, 2025
e887b45
Merge branch 'dev' into aaron/BGS-188/router_limits
aaronArinder Jan 27, 2025
241ccac
gourd
aaronArinder Jan 27, 2025
9462d91
gourd
aaronArinder Jan 27, 2025
10c3e21
gourd
aaronArinder Jan 27, 2025
586640f
gourd
aaronArinder Jan 27, 2025
ee93f15
gourd
aaronArinder Jan 27, 2025
f38ad7f
gourd
aaronArinder Jan 27, 2025
6616208
gourd
aaronArinder Jan 27, 2025
63f2251
gourd
aaronArinder Jan 27, 2025
e0e06e0
Merge remote-tracking branch 'origin/dev' into aaron/BGS-188/router_l…
aaronArinder Jan 28, 2025
a4435c3
gourd
aaronArinder Jan 28, 2025
e43d948
gourd
aaronArinder Jan 28, 2025
a075723
gourd
aaronArinder Jan 28, 2025
a80761a
gourd
aaronArinder Jan 28, 2025
7606d0b
gourd
aaronArinder Jan 28, 2025
1afe8b0
gourd
aaronArinder Jan 28, 2025
9721ae8
Merge branch 'dev' into aaron/BGS-188/router_limits
aaronArinder Jan 28, 2025
8bd67f0
gourd
aaronArinder Jan 28, 2025
38ea8a3
Merge branch 'dev' into aaron/BGS-188/router_limits
aaronArinder Jan 28, 2025
dcfb538
Merge branch 'dev' into aaron/BGS-188/router_limits
aaronArinder Jan 29, 2025
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
5 changes: 5 additions & 0 deletions .changesets/feat_router_limits_plugin.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
### Limiting the router by plugin for certain tiers

Beginning with how many operations are allowed over a certain interval, the router will be limited for free tier users. This adds some mild friction for using the free tier in production while allowing its capabilities to be tested.

By [@aaronarinder](https://github.com/aaronarinder) in https://github.com/apollographql/router/pull/6598
4 changes: 2 additions & 2 deletions apollo-router/src/axum_factory/axum_http_server_factory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -518,7 +518,7 @@ async fn license_handler(
) -> Response {
if matches!(
license,
LicenseState::LicensedHalt | LicenseState::LicensedWarn
LicenseState::LicensedHalt { limits: _ } | LicenseState::LicensedWarn { limits: _ }
) {
// This will rate limit logs about license to 1 a second.
// The way it works is storing the delta in seconds from a starting instant.
Expand All @@ -543,7 +543,7 @@ async fn license_handler(
}
}

if matches!(license, LicenseState::LicensedHalt) {
if matches!(license, LicenseState::LicensedHalt { limits: _ }) {
http::Response::builder()
.status(StatusCode::INTERNAL_SERVER_ERROR)
.body(axum::body::Body::default())
Expand Down
2 changes: 1 addition & 1 deletion apollo-router/src/axum_factory/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ impl<B> MakeSpan<B> for PropagatingMakeSpan {
};
if matches!(
self.license,
LicenseState::LicensedWarn | LicenseState::LicensedHalt
LicenseState::LicensedWarn { limits: _ } | LicenseState::LicensedHalt { limits: _ }
) {
span.record(OTEL_STATUS_CODE, OTEL_STATUS_CODE_ERROR);
span.record("apollo_router.license", LICENSE_EXPIRED_SHORT_MESSAGE);
Expand Down
9 changes: 7 additions & 2 deletions apollo-router/src/configuration/metrics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -541,6 +541,7 @@ mod test {

use crate::configuration::metrics::InstrumentData;
use crate::configuration::metrics::Metrics;
use crate::uplink::license_enforcement::LicenseLimits;
use crate::uplink::license_enforcement::LicenseState;

#[derive(RustEmbed)]
Expand Down Expand Up @@ -575,15 +576,19 @@ mod test {
#[test]
fn test_license_warn() {
let mut data = InstrumentData::default();
data.populate_license_instrument(&LicenseState::LicensedWarn);
data.populate_license_instrument(&LicenseState::LicensedWarn {
limits: Some(LicenseLimits::default()),
});
let _metrics: Metrics = data.into();
assert_non_zero_metrics_snapshot!();
}

#[test]
fn test_license_halt() {
let mut data = InstrumentData::default();
data.populate_license_instrument(&LicenseState::LicensedHalt);
data.populate_license_instrument(&LicenseState::LicensedHalt {
limits: Some(LicenseLimits::default()),
});
let _metrics: Metrics = data.into();
assert_non_zero_metrics_snapshot!();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5090,6 +5090,9 @@ expression: "&schema"
},
"type": "object"
},
"RouterLimitsConfig": {
"type": "object"
},
"RouterRequestConf": {
"additionalProperties": false,
"description": "What information is passed to a router request/response stage",
Expand Down Expand Up @@ -8735,6 +8738,10 @@ expression: "&schema"
"$ref": "#/definitions/Conf7",
"description": "#/definitions/Conf7"
},
"router_limits": {
"$ref": "#/definitions/RouterLimitsConfig",
"description": "#/definitions/RouterLimitsConfig"
},
"sandbox": {
"$ref": "#/definitions/Sandbox",
"description": "#/definitions/Sandbox"
Expand Down
21 changes: 21 additions & 0 deletions apollo-router/src/metrics/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1146,6 +1146,27 @@ macro_rules! assert_histogram_not_exists {
};
}

/// Shared counter for `apollo.router.graphql_error` for consistency
pub(crate) fn count_graphql_error(count: u64, code: Option<&str>) {
match code {
None => {
u64_counter!(
"apollo.router.graphql_error",
"Number of GraphQL error responses returned by the router",
count
);
}
Some(code) => {
u64_counter!(
"apollo.router.graphql_error",
"Number of GraphQL error responses returned by the router",
count,
code = code.to_string()
);
}
}
}

/// Assert that all metrics match an [insta] snapshot.
///
/// Consider using [assert_non_zero_metrics_snapshot] to produce more grokkable snapshots if
Expand Down
3 changes: 3 additions & 0 deletions apollo-router/src/orbiter/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ use crate::router_factory::YamlRouterFactory;
use crate::services::router::service::RouterCreator;
use crate::services::HasSchema;
use crate::spec::Schema;
use crate::uplink::license_enforcement::LicenseState;
use crate::Configuration;

/// This session id is created once when the router starts. It persists between config reloads and supergraph schema changes.
Expand Down Expand Up @@ -100,6 +101,7 @@ impl RouterSuperServiceFactory for OrbiterRouterSuperServiceFactory {
schema: Arc<Schema>,
previous_router: Option<&'a Self::RouterFactory>,
extra_plugins: Option<Vec<(String, Box<dyn DynPlugin>)>>,
license: LicenseState,
) -> Result<Self::RouterFactory, BoxError> {
self.delegate
.create(
Expand All @@ -108,6 +110,7 @@ impl RouterSuperServiceFactory for OrbiterRouterSuperServiceFactory {
schema.clone(),
previous_router,
extra_plugins,
license,
)
.await
.inspect(|factory| {
Expand Down
15 changes: 15 additions & 0 deletions apollo-router/src/plugin/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ use crate::services::execution;
use crate::services::router;
use crate::services::subgraph;
use crate::services::supergraph;
use crate::uplink::license_enforcement::LicenseState;
use crate::ListenAddr;

type InstanceFactory =
Expand Down Expand Up @@ -81,6 +82,9 @@ pub struct PluginInit<T> {
pub(crate) launch_id: Option<Arc<String>>,

pub(crate) notify: Notify<String, graphql::Response>,

/// User's license's state, including any limits of use
pub(crate) license: LicenseState,
}

impl<T> PluginInit<T>
Expand All @@ -103,6 +107,7 @@ where
.supergraph_schema(supergraph_schema)
.launch_id(Arc::new("launch_id".to_string()))
.notify(Notify::for_tests())
.license(LicenseState::default())
.build()
}
}
Expand All @@ -114,6 +119,7 @@ where
{
/// Create a new PluginInit builder
#[builder(entry = "builder", exit = "build", visibility = "pub")]
#[allow(clippy::too_many_arguments)]
/// Build a new PluginInit for the supplied configuration and SDL.
///
/// You can reuse a notify instance, or Build your own.
Expand All @@ -125,6 +131,7 @@ where
subgraph_schemas: Option<Arc<HashMap<String, Arc<Valid<Schema>>>>>,
launch_id: Option<Option<Arc<String>>>,
notify: Notify<String, graphql::Response>,
license: LicenseState,
) -> Self {
PluginInit {
config,
Expand All @@ -134,10 +141,12 @@ where
subgraph_schemas: subgraph_schemas.unwrap_or_default(),
launch_id: launch_id.flatten(),
notify,
license,
}
}

#[builder(entry = "try_builder", exit = "build", visibility = "pub")]
#[allow(clippy::too_many_arguments)]
/// Try to build a new PluginInit for the supplied json configuration and SDL.
///
/// You can reuse a notify instance, or Build your own.
Expand All @@ -150,6 +159,7 @@ where
subgraph_schemas: Option<Arc<HashMap<String, Arc<Valid<Schema>>>>>,
launch_id: Option<Arc<String>>,
notify: Notify<String, graphql::Response>,
license: LicenseState,
) -> Result<Self, BoxError> {
let config: T = serde_json::from_value(config)?;
Ok(PluginInit {
Expand All @@ -160,11 +170,13 @@ where
subgraph_schemas: subgraph_schemas.unwrap_or_default(),
launch_id,
notify,
license,
})
}

/// Create a new PluginInit builder
#[builder(entry = "fake_builder", exit = "build", visibility = "pub")]
#[allow(clippy::too_many_arguments)]
fn fake_new_builder(
config: T,
supergraph_sdl: Option<Arc<String>>,
Expand All @@ -173,6 +185,7 @@ where
subgraph_schemas: Option<Arc<HashMap<String, Arc<Valid<Schema>>>>>,
launch_id: Option<Arc<String>>,
notify: Option<Notify<String, graphql::Response>>,
license: Option<LicenseState>,
) -> Self {
PluginInit {
config,
Expand All @@ -183,6 +196,7 @@ where
subgraph_schemas: subgraph_schemas.unwrap_or_default(),
launch_id,
notify: notify.unwrap_or_else(Notify::for_tests),
license: license.unwrap_or_default(),
}
}
}
Expand All @@ -200,6 +214,7 @@ impl PluginInit<serde_json::Value> {
.supergraph_sdl(self.supergraph_sdl)
.subgraph_schemas(self.subgraph_schemas)
.notify(self.notify.clone())
.license(self.license)
.build()
}
}
Expand Down
2 changes: 2 additions & 0 deletions apollo-router/src/plugins/connectors/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ use crate::router_factory::YamlRouterFactory;
use crate::services::new_service::ServiceFactory;
use crate::services::router::Request;
use crate::services::supergraph;
use crate::uplink::license_enforcement::LicenseState;
use crate::Configuration;

mod mock_api;
Expand Down Expand Up @@ -1785,6 +1786,7 @@ async fn execute(
Arc::new(crate::spec::Schema::parse(schema, &config).unwrap()),
None,
None,
LicenseState::default(),
)
.await
.unwrap();
Expand Down
13 changes: 10 additions & 3 deletions apollo-router/src/plugins/include_subgraph_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -258,9 +258,16 @@ mod test {

let builder = PluggableSupergraphServiceBuilder::new(planner);

let mut plugins = create_plugins(&configuration, &schema, subgraph_schemas, None, None)
.await
.unwrap();
let mut plugins = create_plugins(
&Configuration::default(),
&schema,
subgraph_schemas,
None,
None,
Default::default(),
)
.await
.unwrap();

plugins.insert("apollo.include_subgraph_errors".to_string(), plugin);

Expand Down
1 change: 1 addition & 0 deletions apollo-router/src/plugins/limits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,7 @@ mod test {
let plugin: PluginTestHarness<LimitsPlugin> = PluginTestHarness::new(
Some(include_str!("fixtures/content_length_limit.router.yaml")),
None,
None,
)
.await;
plugin
Expand Down
1 change: 1 addition & 0 deletions apollo-router/src/plugins/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ pub(crate) mod override_url;
pub(crate) mod progressive_override;
mod record_replay;
pub(crate) mod rhai;
pub(crate) mod router_limits;
pub(crate) mod subscription;
pub(crate) mod telemetry;
#[cfg(test)]
Expand Down
Loading