Skip to content

Commit 0c5cff8

Browse files
committed
More
1 parent add93b7 commit 0c5cff8

File tree

6 files changed

+71
-63
lines changed

6 files changed

+71
-63
lines changed

bin/router/src/lib.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use crate::{
1919
},
2020
jwt::JwtAuthRuntime,
2121
logger::configure_logging,
22-
pipeline::graphql_request_handler,
22+
pipeline::{graphql_request_handler, usage_reporting::create_hive_user_agent},
2323
};
2424

2525
pub use crate::{schema_state::SchemaState, shared_state::RouterSharedState};
@@ -110,7 +110,10 @@ pub async fn configure_app_from_config(
110110
true => Some(JwtAuthRuntime::init(bg_tasks_manager, &router_config.jwt).await?),
111111
false => None,
112112
};
113-
let usage_agent = pipeline::usage_reporting::from_config(&router_config).map(Arc::new);
113+
let usage_agent = router_config
114+
.usage_reporting
115+
.as_ref()
116+
.map(|usage_config| Arc::new(create_hive_user_agent(usage_config)));
114117

115118
if let Some(usage_agent) = &usage_agent {
116119
bg_tasks_manager.register_task(usage_agent.clone());

bin/router/src/pipeline/mod.rs

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -192,23 +192,26 @@ pub async fn execute_pipeline(
192192
)
193193
.await?;
194194

195-
shared_state.usage_agent.as_ref().and_then(|usage_agent| {
196-
shared_state
197-
.router_config
198-
.usage_reporting
199-
.as_ref()
200-
.map(|usage_config| {
201-
usage_reporting::send_usage_report(
202-
supergraph.schema.clone(),
203-
start,
204-
req,
205-
&client_request_details,
206-
usage_agent,
207-
usage_config,
208-
&execution_result,
209-
)
210-
})
211-
});
195+
shared_state
196+
.hive_usage_agent
197+
.as_ref()
198+
.and_then(|usage_agent| {
199+
shared_state
200+
.router_config
201+
.usage_reporting
202+
.as_ref()
203+
.map(|usage_config| {
204+
usage_reporting::collect_usage_report(
205+
supergraph.supergraph_schema.clone(),
206+
start.elapsed(),
207+
req,
208+
&client_request_details,
209+
usage_agent,
210+
usage_config,
211+
&execution_result,
212+
)
213+
})
214+
});
212215

213216
Ok(execution_result)
214217
}

bin/router/src/pipeline/usage_reporting.rs

Lines changed: 29 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,40 @@
11
use std::{
22
sync::Arc,
3-
time::{Duration, Instant, SystemTime, UNIX_EPOCH},
3+
time::{Duration, SystemTime, UNIX_EPOCH},
44
};
55

66
use async_trait::async_trait;
77
use graphql_parser::schema::Document;
88
use hive_console_sdk::agent::{ExecutionReport, UsageAgent};
9-
use hive_router_config::{usage_reporting::UsageReportingConfig, HiveRouterConfig};
9+
use hive_router_config::usage_reporting::UsageReportingConfig;
1010
use hive_router_plan_executor::execution::{
1111
client_request_details::ClientRequestDetails, plan::PlanExecutionOutput,
1212
};
1313
use ntex::web::HttpRequest;
1414
use rand::Rng;
1515
use tokio_util::sync::CancellationToken;
1616

17-
use crate::background_tasks::BackgroundTask;
17+
use crate::{background_tasks::BackgroundTask, consts::ROUTER_VERSION};
1818

19-
pub fn from_config(router_config: &HiveRouterConfig) -> Option<UsageAgent> {
20-
router_config.usage_reporting.as_ref().map(|usage_config| {
21-
let flush_interval = Duration::from_secs(usage_config.flush_interval);
22-
hive_console_sdk::agent::UsageAgent::new(
23-
usage_config.token.clone(),
24-
usage_config.endpoint.clone(),
25-
usage_config.target_id.clone(),
26-
usage_config.buffer_size,
27-
usage_config.connect_timeout,
28-
usage_config.request_timeout,
29-
usage_config.accept_invalid_certs,
30-
flush_interval,
31-
"hive-router".to_string(),
32-
)
33-
})
19+
pub fn create_hive_user_agent(usage_config: &UsageReportingConfig) -> UsageAgent {
20+
let user_agent = format!("hive-router/{}", ROUTER_VERSION);
21+
hive_console_sdk::agent::UsageAgent::new(
22+
usage_config.access_token.clone(),
23+
usage_config.endpoint.clone(),
24+
usage_config.target_id.clone(),
25+
usage_config.buffer_size,
26+
usage_config.connect_timeout,
27+
usage_config.request_timeout,
28+
usage_config.accept_invalid_certs,
29+
usage_config.flush_interval,
30+
user_agent,
31+
)
3432
}
3533

36-
pub fn send_usage_report(
34+
#[inline]
35+
pub fn collect_usage_report(
3736
schema: Arc<Document<'static, String>>,
38-
start: Instant,
37+
duration: Duration,
3938
req: &HttpRequest,
4039
client_request_details: &ClientRequestDetails,
4140
usage_agent: &UsageAgent,
@@ -59,13 +58,11 @@ pub fn send_usage_report(
5958
let timestamp = SystemTime::now()
6059
.duration_since(UNIX_EPOCH)
6160
.unwrap()
62-
.as_secs()
63-
* 1000;
64-
let duration = start.elapsed();
61+
.as_millis() as u64;
6562
let execution_report = ExecutionReport {
6663
schema,
67-
client_name,
68-
client_version,
64+
client_name: client_name.map(|s| s.to_owned()),
65+
client_version: client_version.map(|s| s.to_owned()),
6966
timestamp,
7067
duration,
7168
ok: execution_result.error_count == 0,
@@ -77,22 +74,20 @@ pub fn send_usage_report(
7774
.map(|op_name| op_name.to_owned()),
7875
persisted_document_hash: None,
7976
};
80-
usage_agent
81-
.add_report(execution_report)
82-
.unwrap_or_else(|err| tracing::error!("Failed to send usage report: {}", err));
77+
78+
if let Err(err) = usage_agent.add_report(execution_report) {
79+
tracing::error!("Failed to send usage report: {}", err);
80+
}
8381
}
8482

85-
fn get_header_value(req: &HttpRequest, header_name: &str) -> Option<String> {
86-
req.headers()
87-
.get(header_name)
88-
.and_then(|v| v.to_str().ok())
89-
.map(|s| s.to_string())
83+
fn get_header_value<'req>(req: &'req HttpRequest, header_name: &str) -> Option<&'req str> {
84+
req.headers().get(header_name).and_then(|v| v.to_str().ok())
9085
}
9186

9287
#[async_trait]
9388
impl BackgroundTask for UsageAgent {
9489
fn id(&self) -> &str {
95-
"usage_report_flush_interval"
90+
"hive_console_usage_report_task"
9691
}
9792

9893
async fn run(&self, token: CancellationToken) {

bin/router/src/schema_state.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ pub struct SupergraphData {
4040
pub metadata: SchemaMetadata,
4141
pub planner: Planner,
4242
pub subgraph_executor_map: SubgraphExecutorMap,
43-
pub schema: Arc<Document<'static, String>>,
43+
pub supergraph_schema: Arc<Document<'static, String>>,
4444
}
4545

4646
#[derive(Debug, thiserror::Error)]
@@ -126,7 +126,7 @@ impl SchemaState {
126126
)?;
127127

128128
Ok(SupergraphData {
129-
schema: Arc::new(parsed_supergraph_sdl),
129+
supergraph_schema: Arc::new(parsed_supergraph_sdl),
130130
metadata,
131131
planner,
132132
subgraph_executor_map,

bin/router/src/shared_state.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ pub struct RouterSharedState {
1919
pub override_labels_evaluator: OverrideLabelsEvaluator,
2020
pub cors_runtime: Option<Cors>,
2121
pub jwt_auth_runtime: Option<JwtAuthRuntime>,
22-
pub usage_agent: Option<Arc<UsageAgent>>,
22+
pub hive_usage_agent: Option<Arc<UsageAgent>>,
2323
}
2424

2525
impl RouterSharedState {
@@ -39,7 +39,7 @@ impl RouterSharedState {
3939
)
4040
.map_err(Box::new)?,
4141
jwt_auth_runtime,
42-
usage_agent,
42+
hive_usage_agent: usage_agent,
4343
})
4444
}
4545
}
@@ -52,6 +52,6 @@ pub enum SharedStateError {
5252
CORSConfig(#[from] Box<CORSConfigError>),
5353
#[error("invalid override labels config: {0}")]
5454
OverrideLabelsCompile(#[from] Box<OverrideLabelsCompileError>),
55-
#[error("error creating usage agent: {0}")]
55+
#[error("error creating hive usage agent: {0}")]
5656
UsageAgent(#[from] Box<hive_console_sdk::agent::AgentError>),
5757
}

lib/router-config/src/usage_reporting.rs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
1+
use std::time::Duration;
2+
13
use schemars::JsonSchema;
24
use serde::{Deserialize, Serialize};
35

46
#[derive(Debug, Deserialize, Serialize, JsonSchema, Clone)]
57
#[serde(deny_unknown_fields)]
68
pub struct UsageReportingConfig {
79
/// Your [Registry Access Token](https://the-guild.dev/graphql/hive/docs/management/targets#registry-access-tokens) with write permission.
8-
pub token: String,
10+
pub access_token: String,
911
/// A target ID, this can either be a slug following the format “$organizationSlug/$projectSlug/$targetSlug” (e.g “the-guild/graphql-hive/staging”) or an UUID (e.g. “a0f4c605-6541-4350-8cfe-b31f21a4bf80”). To be used when the token is configured with an organization access token.
1012
pub target_id: Option<String>,
1113
/// For self-hosting, you can override `/usage` endpoint (defaults to `https://app.graphql-hive.com/usage`).
@@ -45,8 +47,13 @@ pub struct UsageReportingConfig {
4547
pub request_timeout: u64,
4648
/// Frequency of flushing the buffer to the server
4749
/// Default: 5 seconds
48-
#[serde(default = "default_flush_interval")]
49-
pub flush_interval: u64,
50+
#[serde(
51+
default = "default_flush_interval",
52+
deserialize_with = "humantime_serde::deserialize",
53+
serialize_with = "humantime_serde::serialize"
54+
)]
55+
#[schemars(with = "String")]
56+
pub flush_interval: Duration,
5057
}
5158

5259
fn default_endpoint() -> String {
@@ -81,6 +88,6 @@ fn default_connect_timeout() -> u64 {
8188
5
8289
}
8390

84-
fn default_flush_interval() -> u64 {
85-
5
91+
fn default_flush_interval() -> Duration {
92+
Duration::from_secs(5)
8693
}

0 commit comments

Comments
 (0)