diff --git a/Cargo.lock b/Cargo.lock index 3fc69ee6..c3e55539 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4748,9 +4748,9 @@ dependencies = [ [[package]] name = "unleash-types" -version = "0.15.4" +version = "0.15.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e00ce8bb376d199edf068d04756f9cee78a561dbdb4cf49ebcad35cb452e3d5" +checksum = "69d8bb918dfb2bcbf1019646c25c05d8ab5093d5e28820decc300f4239f3342c" dependencies = [ "base64 0.22.1", "chrono", @@ -4763,9 +4763,9 @@ dependencies = [ [[package]] name = "unleash-yggdrasil" -version = "0.14.6" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7658e226f9bc375aaeb408321f7d7803a4d4d58b297e40fb8ea72930671cb06" +checksum = "62d78da44a08b062d7c46bd64cc3d7f225c39adc77d35ec2a22935ce8208289b" dependencies = [ "chrono", "convert_case 0.6.0", diff --git a/server/Cargo.toml b/server/Cargo.toml index 773c19db..f45974fd 100644 --- a/server/Cargo.toml +++ b/server/Cargo.toml @@ -95,8 +95,8 @@ tokio-stream = { version = "0.1.17" } tracing = { version = "0.1.41", features = ["log"] } tracing-subscriber = { version = "0.3.19", features = ["json", "env-filter"] } ulid = "1.1.4" -unleash-types = { version = "0.15.4", features = ["openapi", "hashes"] } -unleash-yggdrasil = { version = "0.14.6" } +unleash-types = { version = "0.15.5", features = ["openapi", "hashes"] } +unleash-yggdrasil = { version = "0.16.0" } utoipa = { version = "5.3.1", features = ["actix_extras", "chrono"] } utoipa-swagger-ui = { version = "9.0.0", features = ["actix-web"] } [dev-dependencies] diff --git a/server/src/feature_cache.rs b/server/src/feature_cache.rs index 3e1021e3..7c326bea 100644 --- a/server/src/feature_cache.rs +++ b/server/src/feature_cache.rs @@ -70,8 +70,8 @@ impl FeatureCache { pub fn apply_delta(&self, key: String, delta: &ClientFeaturesDelta) { let client_features = ClientFeatures { version : 2, - features : delta.updated.clone(), - segments: delta.segments.clone(), + features : vec![], + segments: Some(vec![]), query: None, meta: None, }; @@ -80,7 +80,7 @@ impl FeatureCache { .and_modify(|existing_features| { existing_features.modify_in_place(delta); }) - .or_insert(client_features); + .or_insert(client_features.modify_and_copy(delta)); self.send_full_update(key); } diff --git a/server/src/http/refresher/delta_refresher.rs b/server/src/http/refresher/delta_refresher.rs index 4fb369f2..c9acce58 100644 --- a/server/src/http/refresher/delta_refresher.rs +++ b/server/src/http/refresher/delta_refresher.rs @@ -16,11 +16,10 @@ impl FeatureRefresher { delta: ClientFeaturesDelta, etag: Option, ) { - let updated_len = delta.updated.len(); - let removed_len = delta.removed.len(); + let updated_len = delta.events.len(); debug!( - "Got updated client features delta. Updating features with {etag:?}, updated {updated_len}, removed {removed_len}" + "Got updated client features delta. Updating features with {etag:?}, events count {updated_len}" ); let key = cache_key(refresh_token); @@ -129,9 +128,7 @@ mod tests { use crate::http::refresher::feature_refresher::FeatureRefresher; use crate::http::unleash_client::{ClientMetaInformation, UnleashClient}; use crate::types::EdgeToken; - use unleash_types::client_features::{ - ClientFeature, ClientFeatures, ClientFeaturesDelta, Constraint, Operator, Segment, - }; + use unleash_types::client_features::{ClientFeature, ClientFeatures, ClientFeaturesDelta, Constraint, DeltaEvent, Operator, Segment}; use unleash_yggdrasil::EngineState; #[actix_web::test] @@ -201,45 +198,59 @@ mod tests { fn revision(revision_id: u32) -> ClientFeaturesDelta { match revision_id { 1 => ClientFeaturesDelta { - updated: vec![ - ClientFeature { - name: "test1".into(), - feature_type: Some("release".into()), - ..Default::default() + events: vec![ + DeltaEvent::FeatureUpdated { + event_id: 1, + feature: ClientFeature { + name: "test1".into(), + feature_type: Some("release".into()), + ..Default::default() + }, }, - ClientFeature { - name: "test2".into(), - feature_type: Some("release".into()), - ..Default::default() + DeltaEvent::FeatureUpdated { + event_id: 1, + feature: ClientFeature { + name: "test2".into(), + feature_type: Some("release".into()), + ..Default::default() + }, + }, + DeltaEvent::SegmentUpdated { + event_id: 1, + segment: Segment { + id: 1, + constraints: vec![Constraint { + context_name: "userId".into(), + operator: Operator::In, + case_insensitive: false, + inverted: false, + values: Some(vec!["7".into()]), + value: None, + }], + }, }, ], - removed: vec![], - segments: Some(vec![Segment { - id: 1, - constraints: vec![Constraint { - context_name: "userId".into(), - operator: Operator::In, - case_insensitive: false, - inverted: false, - values: Some(vec!["7".into()]), - value: None, - }], - }]), - revision_id: 1, }, _ => ClientFeaturesDelta { - updated: vec![ClientFeature { - name: "test1".into(), - feature_type: Some("release".into()), - ..Default::default() - }], - removed: vec!["test2".to_string()], - segments: None, - revision_id: 2, + events: vec![ + DeltaEvent::FeatureUpdated { + event_id: 2, + feature: ClientFeature { + name: "test1".into(), + feature_type: Some("release".into()), + ..Default::default() + }, + }, + DeltaEvent::FeatureRemoved { + event_id: 2, + feature_name: "test2".to_string(), + }, + ], }, } } + async fn return_client_features_delta(etag_header: Option) -> HttpResponse { match etag_header { Some(value) => match value.as_str() { diff --git a/server/src/http/refresher/feature_refresher.rs b/server/src/http/refresher/feature_refresher.rs index 868aab52..51d43a0b 100644 --- a/server/src/http/refresher/feature_refresher.rs +++ b/server/src/http/refresher/feature_refresher.rs @@ -9,7 +9,7 @@ use futures::TryStreamExt; use json_structural_diff::JsonDiff; use reqwest::StatusCode; use tracing::{debug, info, warn}; -use unleash_types::client_features::{ClientFeatures}; +use unleash_types::client_features::{ClientFeatures, DeltaEvent}; use unleash_types::client_metrics::{ClientApplication, MetricsMetadata}; use unleash_yggdrasil::EngineState; @@ -411,7 +411,16 @@ impl FeatureRefresher { if let Some(client_features) = self.features_cache.get(&key).as_ref() { if let Ok(ClientFeaturesDeltaResponse::Updated(delta_features, _etag)) = delta_result { let c_features = &client_features.features; - let d_features = delta_features.updated; + let d_features = delta_features + .events + .iter() + .find_map(|event| { + if let DeltaEvent::Hydration { features, .. } = event { + Some(features) + } else { + None + } + }); let delta_json = serde_json::to_value(d_features).unwrap(); let client_json = serde_json::to_value(c_features).unwrap();