Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
9 changes: 9 additions & 0 deletions NEXT_CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,20 @@ By [@bnjjj](https://github.com/bnjjj) in https://github.com/apollographql/router

## 🐛 Fixes

### Follow directives from Uplink ([Issue #1494](https://github.com/apollographql/router/issues/1494) [Issue #1539](https://github.com/apollographql/router/issues/1539))

The Uplink API returns actionable info in its responses:
- some error codes indicate an unrecoverable issue, for which the router should not retry the query (example: non-existing graph)
- it can tell the router when it should retry the query

By [@Geal](https://github.com/Geal) in https://github.com/apollographql/router/pull/2001

### Fix the rhai SDL print function [Issue #2005](https://github.com/apollographql/router/issues/2005))

A recent change to the way we provide the SDL to plugins broke the rhai SDL print. This fixes it.

By [@fernando-apollo](https://github.com/fernando-apollo) in https://github.com/apollographql/router/pull/2007

## 🛠 Maintenance

### Split the configuration file management in multiple modules [Issue #1790](https://github.com/apollographql/router/issues/1790))
Expand Down
5 changes: 1 addition & 4 deletions apollo-router/src/router.rs
Original file line number Diff line number Diff line change
Expand Up @@ -229,10 +229,7 @@ impl SchemaSource {
future::ready(match res {
Ok(schema_result) => Some(UpdateSchema(schema_result.schema)),
Err(e) => {
tracing::error!(
"error downloading the schema from Uplink: {:?}",
e
);
tracing::error!("{}", e);
None
}
})
Expand Down
52 changes: 29 additions & 23 deletions apollo-router/src/uplink/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ use tokio_stream::wrappers::ReceiverStream;
use tracing::instrument::WithSubscriber;
use url::Url;

use self::supergraph_sdl::SupergraphSdlRouterConfigOnFetchError;

const GCP_URL: &str = "https://uplink.api.apollographql.com/graphql";
const AWS_URL: &str = "https://aws.uplink.api.apollographql.com/graphql";

Expand All @@ -35,13 +37,6 @@ pub(crate) struct SupergraphSdl;
pub(crate) enum Error {
Reqwest(reqwest::Error),
EmptyResponse,
UpLink {
// The lint ignores uses in the `Debug` impl, but this is where these fields are useful.
#[allow(dead_code)]
code: FetchErrorCode,
#[allow(dead_code)]
message: String,
},
}

impl From<reqwest::Error> for Error {
Expand All @@ -60,14 +55,13 @@ pub(crate) fn stream_supergraph(
api_key: String,
graph_ref: String,
urls: Option<Vec<Url>>,
interval: Duration,
) -> impl Stream<Item = Result<Schema, Error>> {
mut interval: Duration,
) -> impl Stream<Item = Result<Schema, String>> {
let (sender, receiver) = channel(2);
let _ = tokio::task::spawn(async move {
let mut composition_id = None;

let mut interval = tokio::time::interval(interval);
let mut current_url_idx = 0;

loop {
match fetch_supergraph(
api_key.to_string(),
Expand All @@ -91,38 +85,50 @@ pub(crate) fn stream_supergraph(
{
break;
}
// this will truncate the number of seconds to under u64::MAX, which should be
// a large enough delay anyway
interval = Duration::from_secs(schema_config.min_delay_seconds.round() as u64);
}
supergraph_sdl::SupergraphSdlRouterConfig::Unchanged => {
tracing::trace!("schema did not change");
}
supergraph_sdl::SupergraphSdlRouterConfig::FetchError(e) => {
if let Some(urls) = &urls {
current_url_idx = (current_url_idx + 1) % urls.len();
supergraph_sdl::SupergraphSdlRouterConfig::FetchError(
SupergraphSdlRouterConfigOnFetchError { code, message },
) => {
if code == FetchErrorCode::RETRY_LATER {
if let Some(urls) = &urls {
current_url_idx = (current_url_idx + 1) % urls.len();
}

if sender
.send(Err(format!("error downloading the schema from Uplink: {}", message)))
.await
.is_err()
{
break;
}
if sender
.send(Err(Error::UpLink {
code: e.code,
message: e.message,
}))
} else {
if sender
.send(Err(format!("{:?} error downloading the schema from Uplink, the router will not try again: {}", code, message)))
.await
.is_err()
{
break;
}
break;
}
}
},
Err(err) => {
tracing::error!("error fetching supergraph from Uplink: {:?}", err);
if let Some(urls) = &urls {
current_url_idx = (current_url_idx + 1) % urls.len();
}
if sender.send(Err(err)).await.is_err() {
break;
}
tracing::error!("error downloading the schema from Uplink: {:?}", err);
}
}

interval.tick().await;
tokio::time::sleep(interval).await;
}
})
.with_current_subscriber();
Expand Down
1 change: 1 addition & 0 deletions apollo-router/src/uplink/query.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ query SupergraphSdl($apiKey: String!, $graph_ref: String!, $ifAfterId: ID) {
... on RouterConfigResult {
id
supergraphSdl: supergraphSDL
minDelaySeconds
}
... on FetchError {
code
Expand Down