Skip to content

Commit 758aed9

Browse files
committed
Merge remote-tracking branch 'upstream/main' into doc/description-optional
2 parents 9ddf360 + 741b241 commit 758aed9

File tree

5 files changed

+37
-21
lines changed

5 files changed

+37
-21
lines changed

.github/workflows/pre-commit.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ jobs:
1010
runs-on: ubuntu-latest
1111
steps:
1212
- uses: actions/checkout@v5
13-
- uses: actions/setup-python@v5
13+
- uses: actions/setup-python@v6
1414
- name: Run pre-commit
1515
run: |
1616
pip install pre-commit

examples/demo.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,13 +60,11 @@ fn main() -> std::result::Result<(), Box<dyn Error>> {
6060
city: "Bangalore".to_string(),
6161
radius: 60,
6262
};
63-
63+
thread::sleep(Duration::from_secs(5));
6464
println!("The information is displayed every 5 seconds.");
6565
println!("Try changing the configuraiton in the App Configuration instances.");
6666

6767
loop {
68-
println!("\n\nFEATURE FLAG OPERATIONS\n");
69-
7068
match client.get_feature_proxy(&feature_id) {
7169
Ok(feature) => {
7270
println!("Feature name: {}", feature.get_name()?);
@@ -78,8 +76,6 @@ fn main() -> std::result::Result<(), Box<dyn Error>> {
7876
println!("There was an error getting the Feature Flag. Error {error}",);
7977
}
8078
}
81-
82-
println!("\n\nPROPERTY OPERATIONS\n");
8379
match client.get_property_proxy(&property_id) {
8480
Ok(property) => {
8581
println!("Property name: {}", property.get_name()?);

src/metering/client_http.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ impl MeteringClientHttp {
2929
impl MeteringClient for MeteringClientHttp {
3030
fn push_metering_data(&self, guid: &str, data: &MeteringDataJson) -> MeteringResult<()> {
3131
let url = format!(
32-
"{}/apprapp/events/v1/instances/{}/usage",
32+
"{}/events/v1/instances/{}/usage",
3333
self.service_address.base_url(ServiceAddressProtocol::Http),
3434
guid
3535
);
@@ -82,7 +82,7 @@ pub(crate) mod tests {
8282
let server = MockServer::start();
8383
let mock = server.mock(|when, then| {
8484
when.method(POST)
85-
.path("/apprapp/events/v1/instances/example_guid/usage")
85+
.path("/events/v1/instances/example_guid/usage")
8686
.header("content-type", "application/json")
8787
.header("Authorization", "Bearer mocked_token")
8888
.json_body(json!(

src/metering/metering.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15+
use log::debug;
1516
use log::warn;
1617

1718
use crate::metering::models::{
@@ -46,6 +47,7 @@ pub(crate) fn start_metering<T: MeteringClient>(
4647
let thread = ThreadHandle::new(move |_terminator: mpsc::Receiver<()>| {
4748
let mut batcher = MeteringBatcher::new(client, config_id);
4849
let mut last_flush = std::time::Instant::now();
50+
debug!("Starting Metering transmitting thread");
4951
loop {
5052
let recv_result = receiver.recv_timeout(std::time::Duration::from_millis(100));
5153
match recv_result {
@@ -196,9 +198,19 @@ impl<T: MeteringClient> MeteringBatcher<T> {
196198
json_data.add_usage(evaluation.0, evaluation.1);
197199
}
198200

199-
let _ = self
201+
debug!(
202+
"Sending metering data for {} usages.",
203+
json_data.usages.len()
204+
);
205+
let result = self
200206
.client
201207
.push_metering_data(&self.config_id.guid, &json_data);
208+
match result {
209+
Err(err) => {
210+
warn!("Sending metering data failed: {}", err);
211+
}
212+
_ => {}
213+
}
202214
self.evaluations.clear();
203215
}
204216
}

src/models/feature_snapshot.rs

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -99,9 +99,14 @@ impl FeatureSnapshot {
9999
}
100100
}
101101

102+
fn normalized_hash(data: &str) -> u32 {
103+
let hash = murmur3_32(&mut Cursor::new(data), 0).expect("Cannot hash the value.");
104+
(f64::from(hash) / f64::from(u32::MAX) * 100.0) as u32
105+
}
106+
102107
fn should_rollout(rollout_percentage: u32, entity: &impl Entity, feature_id: &str) -> bool {
103108
let tag = format!("{}:{}", entity.get_id(), feature_id);
104-
rollout_percentage == 100 || random_value(&tag) < rollout_percentage
109+
rollout_percentage == 100 || Self::normalized_hash(&tag) < rollout_percentage
105110
}
106111

107112
fn use_rollout_percentage_to_get_value_from_feature_directly(
@@ -139,15 +144,6 @@ impl Feature for FeatureSnapshot {
139144
}
140145
}
141146

142-
pub(crate) fn random_value(v: &str) -> u32 {
143-
let max_hash = u32::MAX;
144-
(f64::from(hash(v)) / f64::from(max_hash) * 100.0) as u32
145-
}
146-
147-
fn hash(v: &str) -> u32 {
148-
murmur3_32(&mut Cursor::new(v), 0).expect("Cannot hash the value.")
149-
}
150-
151147
#[cfg(test)]
152148
pub mod tests {
153149

@@ -213,7 +209,9 @@ pub mod tests {
213209
attributes: entity_attributes.clone(),
214210
};
215211
assert_eq!(
216-
random_value(format!("{}:{}", entity.id, feature.feature_id).as_str()),
212+
FeatureSnapshot::normalized_hash(
213+
format!("{}:{}", entity.id, feature.feature_id).as_str()
214+
),
217215
68
218216
);
219217
let value = feature.get_value(&entity).unwrap();
@@ -225,7 +223,9 @@ pub mod tests {
225223
attributes: entity_attributes,
226224
};
227225
assert_eq!(
228-
random_value(format!("{}:{}", entity.id, feature.feature_id).as_str()),
226+
FeatureSnapshot::normalized_hash(
227+
format!("{}:{}", entity.id, feature.feature_id).as_str()
228+
),
229229
29
230230
);
231231
let value = feature.get_value(&entity).unwrap();
@@ -407,4 +407,12 @@ pub mod tests {
407407
let value = feature.get_value(&entity).unwrap();
408408
assert!(matches!(value, Value::Int64(ref v) if v == &2));
409409
}
410+
411+
/// This test ensures that the rust client is using the same hashing algorithm as to other clients.
412+
/// See same test for Node client:
413+
/// https://github.com/IBM/appconfiguration-node-sdk/blob/master/test/unit/configurations/internal/utils.test.js#L25
414+
#[test]
415+
fn test_normalized_hash() {
416+
assert_eq!(FeatureSnapshot::normalized_hash("entityId:featureId"), 41)
417+
}
410418
}

0 commit comments

Comments
 (0)