Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add migration op tracker #74

Merged
merged 1 commit into from
May 10, 2024
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
2 changes: 1 addition & 1 deletion launchdarkly-server-sdk/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ lazy_static = "1.4.0"
log = "0.4.14"
lru = { version = "0.12.0", default-features = false }
ring = "0.17.5"
launchdarkly-server-sdk-evaluation = "1.2.0"
launchdarkly-server-sdk-evaluation = { git = "https://github.com/launchdarkly/rust-server-sdk-evaluation", branch = "mk/sc-243562/detail-serialize" }
serde = { version = "1.0.132", features = ["derive"] }
serde_json = { version = "1.0.73", features = ["float_roundtrip"] }
thiserror = "1.0"
Expand Down
12 changes: 11 additions & 1 deletion launchdarkly-server-sdk/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ use super::evaluation::{FlagDetail, FlagDetailConfig};
use super::stores::store::DataStore;
use super::stores::store_builders::BuildError as DataStoreError;
use crate::config::BuildError as ConfigBuildError;
use crate::events::event::EventFactory;
use crate::events::event::InputEvent;
use crate::events::event::{EventFactory, MigrationOpEvent};
use crate::events::processor::EventProcessor;
use crate::events::processor_builders::BuildError as EventProcessorError;

Expand Down Expand Up @@ -678,6 +678,16 @@ impl Client {
Ok(())
}

/// track_migration_op_reports a migration operation event.
///
/// The measurements included in the event are used by LaunchDarkly to enhance support and
/// visibility during migration-assisted technology migrations.
///
/// Migration operation events can be created with a [crate::MigrationOpTracker].
pub fn track_migration_op(_event: MigrationOpEvent) {
// TODO: Implement in a future commit.
}

fn variation_internal<T: Into<FlagValue> + Clone>(
&self,
context: &Context,
Expand Down
22 changes: 21 additions & 1 deletion launchdarkly-server-sdk/src/events/event.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
use std::cmp::{max, min};
use std::collections::{HashMap, HashSet};
use std::fmt::{self, Display, Formatter};
use std::time::Duration;

use launchdarkly_server_sdk_evaluation::{
Context, ContextAttributes, Detail, Flag, FlagValue, Kind, Reason, Reference, VariationIndex,
};
use serde::ser::SerializeStruct;
use serde::{Serialize, Serializer};

use crate::migrations::{Operation, Origin, Stage};

#[derive(Clone, Debug, PartialEq)]
pub struct BaseEvent {
pub creation_date: u64,
Expand Down Expand Up @@ -92,6 +95,23 @@ impl BaseEvent {
}
}

#[derive(Clone, Debug, Serialize)]
#[serde(rename_all = "camelCase")]
/// MigrationOpEventData is generated through the migration op tracker provided through the SDK.
pub struct MigrationOpEvent {
#[serde(flatten)]
pub(crate) base: BaseEvent,
pub(crate) flag: Flag,
pub(crate) operation: Operation,
pub(crate) default_stage: Stage,
pub(crate) evaluation: Detail<FlagValue>,
pub(crate) invoked: HashSet<Origin>,
#[serde(skip_serializing_if = "Option::is_none")]
pub(crate) consistency_check: Option<bool>,
pub(crate) errors: HashSet<Origin>,
pub(crate) latency: HashMap<Origin, Duration>,
}

#[derive(Clone, Debug, PartialEq, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct FeatureRequestEvent {
Expand Down Expand Up @@ -290,7 +310,7 @@ impl EventFactory {
Self { send_reason }
}

fn now() -> u64 {
pub(crate) fn now() -> u64 {
std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap()
Expand Down
3 changes: 3 additions & 0 deletions launchdarkly-server-sdk/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ pub use data_source_builders::{
BuildError as DataSourceBuildError, PollingDataSourceBuilder, StreamingDataSourceBuilder,
};
pub use evaluation::{FlagDetail, FlagDetailConfig};
pub use events::event::MigrationOpEvent;
pub use events::processor::EventProcessor;
pub use events::processor_builders::{
BuildError as EventProcessorBuildError, EventProcessorBuilder, NullEventProcessorBuilder,
Expand All @@ -40,6 +41,7 @@ pub use feature_requester_builders::{
BuildError as FeatureRequestBuilderError, FeatureRequesterFactory,
};
pub use launchdarkly_server_sdk_evaluation::{Flag, Segment, Versioned};
pub use migrations::{MigrationOpTracker, Operation, Origin, Stage};
pub use service_endpoints::ServiceEndpointsBuilder;
pub use stores::persistent_store::{PersistentDataStore, PersistentStoreError};
pub use stores::persistent_store_builders::{
Expand All @@ -56,6 +58,7 @@ mod evaluation;
mod events;
mod feature_requester;
mod feature_requester_builders;
mod migrations;
mod reqwest;
mod service_endpoints;
mod stores;
Expand Down
49 changes: 49 additions & 0 deletions launchdarkly-server-sdk/src/migrations/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
use serde::Serialize;

#[non_exhaustive]
#[derive(Debug, Clone, Serialize, Eq, Hash, PartialEq)]
#[serde(rename_all = "lowercase")]
/// Origin represents the source of origin for a migration-related operation.
pub enum Origin {
/// Old represents the technology source we are migrating away from.
Old,
/// New represents the technology source we are migrating towards.
New,
}

#[non_exhaustive]
#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "lowercase")]
/// Operation represents a type of migration operation; namely, read or write.
pub enum Operation {
/// Read denotes a read-related migration operation.
Read,
/// Write denotes a write-related migration operation.
Write,
}

#[non_exhaustive]
#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "lowercase")]
/// Stage denotes one of six possible stages a technology migration could be a
/// part of, progressing through the following order.
///
/// Off -> DualWrite -> Shadow -> Live -> RampDown -> Complete
pub enum Stage {
/// Off - migration hasn't started, "old" is authoritative for reads and writes
Off,
/// DualWrite - write to both "old" and "new", "old" is authoritative for reads
DualWrite,
/// Shadow - both "new" and "old" versions run with a preference for "old"
Shadow,
/// Live - both "new" and "old" versions run with a preference for "new"
Live,
/// RampDown - only read from "new", write to "old" and "new"
Rampdown,
/// Complete - migration is done
Complete,
}

pub use tracker::MigrationOpTracker;

mod tracker;
Loading