Skip to content

Commit 5f1ab69

Browse files
authored
feat: unleash-interval header (#96)
1 parent 10dfd57 commit 5f1ab69

File tree

2 files changed

+51
-34
lines changed

2 files changed

+51
-34
lines changed

src/client.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -800,15 +800,18 @@ where
800800
self.polling.store(true, Ordering::Relaxed);
801801
loop {
802802
debug!("poll: retrieving features");
803-
let res = self.http.get_json(&endpoint).await;
803+
let res = self.http.get_json(&endpoint, Some(self.interval)).await;
804804
if let Ok(res) = res {
805805
let features: Features = res;
806806
match self.memoize(features.features) {
807807
Ok(None) => {}
808808
Ok(Some(metrics)) => {
809809
if !self.disable_metric_submission {
810810
let mut metrics_uploaded = false;
811-
let res = self.http.post_json(&metrics_endpoint, metrics).await;
811+
let res = self
812+
.http
813+
.post_json(&metrics_endpoint, metrics, Some(self.interval))
814+
.await;
812815
if let Ok(successful) = res {
813816
if successful {
814817
metrics_uploaded = true;
@@ -856,7 +859,7 @@ where
856859
};
857860
let success = self
858861
.http
859-
.post_json(&Registration::endpoint(&self.api_url), &registration)
862+
.post_json(&Registration::endpoint(&self.api_url), &registration, None)
860863
.await
861864
.map_err(|err| anyhow::anyhow!(err))?;
862865
if !success {

src/http.rs

+45-31
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,20 @@ where
6767
}
6868

6969
/// Make a get request and parse into JSON
70-
pub async fn get_json<T: DeserializeOwned>(&self, endpoint: &str) -> Result<T, C::Error> {
71-
C::get_json(self.get(endpoint)).await
70+
pub async fn get_json<T: DeserializeOwned>(
71+
&self,
72+
endpoint: &str,
73+
interval: Option<u64>,
74+
) -> Result<T, C::Error> {
75+
let mut request = self.get(endpoint);
76+
if let Some(interval) = interval {
77+
request = C::header(
78+
request,
79+
&C::build_header("unleash-interval")?,
80+
&interval.to_string(),
81+
);
82+
}
83+
C::get_json(request).await
7284
}
7385

7486
/// Perform a POST. Returns errors per HttpClient::post.
@@ -83,8 +95,17 @@ where
8395
&self,
8496
endpoint: &str,
8597
content: T,
98+
interval: Option<u64>,
8699
) -> Result<bool, C::Error> {
87-
C::post_json(self.post(endpoint), &content).await
100+
let mut request = self.post(endpoint);
101+
if let Some(interval) = interval {
102+
request = C::header(
103+
request,
104+
&C::build_header("unleash-interval")?,
105+
&interval.to_string(),
106+
);
107+
}
108+
C::post_json(request, &content).await
88109
}
89110

90111
fn attach_headers(&self, request: C::RequestBuilder) -> C::RequestBuilder {
@@ -114,11 +135,14 @@ mod tests {
114135
use super::*;
115136
use async_trait::async_trait;
116137
use regex::Regex;
138+
use serde_json::json;
139+
use std::collections::HashMap;
140+
use std::sync::{Arc, RwLock};
117141
use uuid::Uuid;
118142

119143
#[derive(Clone, Default)]
120144
struct MockHttpClient {
121-
headers: std::collections::HashMap<String, String>,
145+
headers: Arc<RwLock<HashMap<String, String>>>,
122146
}
123147

124148
#[async_trait]
@@ -131,8 +155,10 @@ mod tests {
131155
Ok(name.to_string())
132156
}
133157

134-
fn header(mut builder: Self, key: &Self::HeaderName, value: &str) -> Self::RequestBuilder {
135-
builder.headers.insert(key.clone(), value.to_string());
158+
fn header(builder: Self, key: &Self::HeaderName, value: &str) -> Self::RequestBuilder {
159+
if let Ok(mut headers) = builder.headers.write() {
160+
headers.insert(key.clone(), value.to_string());
161+
}
136162
builder
137163
}
138164

@@ -147,14 +173,14 @@ mod tests {
147173
async fn get_json<T: DeserializeOwned>(
148174
_req: Self::RequestBuilder,
149175
) -> Result<T, Self::Error> {
150-
unimplemented!()
176+
Ok(serde_json::from_value(json!({})).unwrap())
151177
}
152178

153179
async fn post_json<T: Serialize + Sync>(
154180
_req: Self::RequestBuilder,
155181
_content: &T,
156182
) -> Result<bool, Self::Error> {
157-
unimplemented!()
183+
Ok(true)
158184
}
159185
}
160186

@@ -168,41 +194,29 @@ mod tests {
168194
)
169195
.unwrap();
170196

171-
let request_builder = http_client.client.post("http://example.com");
172-
let request_with_headers = http_client.attach_headers(request_builder);
197+
let _ = http_client
198+
.get_json::<serde_json::Value>("http://example.com", Some(15))
199+
.await;
200+
let headers = &http_client.client.headers.read().unwrap();
173201

202+
assert_eq!(headers.get("unleash-appname").unwrap(), "my_app");
203+
assert_eq!(headers.get("instance_id").unwrap(), "my_instance_id");
174204
assert_eq!(
175-
request_with_headers.headers.get("unleash-appname").unwrap(),
176-
"my_app"
177-
);
178-
assert_eq!(
179-
request_with_headers.headers.get("instance_id").unwrap(),
180-
"my_instance_id"
181-
);
182-
assert_eq!(
183-
request_with_headers
184-
.headers
185-
.get("unleash-connection-id")
186-
.unwrap(),
205+
headers.get("unleash-connection-id").unwrap(),
187206
"d512f8ec-d972-40a5-9a30-a0a6e85d93ac"
188207
);
189-
assert_eq!(
190-
request_with_headers.headers.get("authorization").unwrap(),
191-
"auth_token"
192-
);
208+
assert_eq!(headers.get("unleash-interval").unwrap(), "15");
209+
assert_eq!(headers.get("authorization").unwrap(), "auth_token");
193210

194211
let version_regex = Regex::new(r"^unleash-client-rust:\d+\.\d+\.\d+$").unwrap();
195-
let sdk_version = request_with_headers.headers.get("unleash-sdk").unwrap();
212+
let sdk_version = headers.get("unleash-sdk").unwrap();
196213
assert!(
197214
version_regex.is_match(sdk_version),
198215
"Version output did not match expected format: {}",
199216
sdk_version
200217
);
201218

202-
let connection_id = request_with_headers
203-
.headers
204-
.get("unleash-connection-id")
205-
.unwrap();
219+
let connection_id = headers.get("unleash-connection-id").unwrap();
206220
assert!(
207221
Uuid::parse_str(connection_id).is_ok(),
208222
"Connection ID is not a valid UUID"

0 commit comments

Comments
 (0)