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

Keep track of the RRD protocol version and display it where relevant #6324

Merged
merged 12 commits into from
May 14, 2024
7 changes: 7 additions & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4152,6 +4152,9 @@ dependencies = [
[[package]]
name = "re_build_info"
version = "0.16.0-alpha.4"
dependencies = [
"serde",
]

[[package]]
name = "re_build_tools"
Expand Down Expand Up @@ -4188,6 +4191,7 @@ dependencies = [
"once_cell",
"parking_lot",
"rayon",
"re_build_info",
"re_build_tools",
"re_log",
"re_log_encoding",
Expand Down Expand Up @@ -4317,6 +4321,7 @@ dependencies = [
"nohash-hasher",
"parking_lot",
"rand",
"re_build_info",
"re_data_store",
"re_format",
"re_int_histogram",
Expand Down Expand Up @@ -4428,6 +4433,7 @@ dependencies = [
"num-derive",
"num-traits",
"re_arrow2",
"re_build_info",
"re_format",
"re_format_arrow",
"re_log",
Expand Down Expand Up @@ -4613,6 +4619,7 @@ dependencies = [
"crossbeam",
"document-features",
"rand",
"re_build_info",
"re_log",
"re_log_encoding",
"re_log_types",
Expand Down
32 changes: 24 additions & 8 deletions crates/re_analytics/src/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@ pub struct StoreInfo {
/// Where data is being logged.
pub store_source: String,

/// The Rerun version that was used to encode the RRD data.
pub store_version: String,

// Various versions of the host environment.
pub rust_version: Option<String>,
pub llvm_version: Option<String>,
Expand Down Expand Up @@ -193,16 +196,29 @@ impl Properties for OpenRecording {
event.insert("app_env", app_env);

if let Some(store_info) = store_info {
event.insert("application_id", store_info.application_id);
event.insert("recording_id", store_info.recording_id);
event.insert("store_source", store_info.store_source);
event.insert_opt("rust_version", store_info.rust_version);
event.insert_opt("llvm_version", store_info.llvm_version);
event.insert_opt("python_version", store_info.python_version);
event.insert("is_official_example", store_info.is_official_example);
let StoreInfo {
application_id,
recording_id,
store_source,
store_version,
rust_version,
llvm_version,
python_version,
is_official_example,
app_id_starts_with_rerun_example,
} = store_info;
Comment on lines +199 to +209
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got bitten by the lack of de-structuring here


event.insert("application_id", application_id);
event.insert("recording_id", recording_id);
event.insert("store_source", store_source);
event.insert("store_version", store_version);
event.insert_opt("rust_version", rust_version);
event.insert_opt("llvm_version", llvm_version);
event.insert_opt("python_version", python_version);
event.insert("is_official_example", is_official_example);
event.insert(
"app_id_starts_with_rerun_example",
store_info.app_id_starts_with_rerun_example,
app_id_starts_with_rerun_example,
);
}

Expand Down
13 changes: 13 additions & 0 deletions crates/re_build_info/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,16 @@ workspace = true

[package.metadata.docs.rs]
all-features = true


[features]
default = []

## Enable (de)serialization using serde.
serde = ["dep:serde"]


[dependencies]

# Optional dependencies:
serde = { workspace = true, optional = true, features = ["derive", "rc"] }
6 changes: 6 additions & 0 deletions crates/re_build_info/src/crate_version.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,20 @@ mod meta {
/// - `01NNNNNN` -> `-rc.N`
/// - `00000000` -> none of the above
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub struct CrateVersion {
pub major: u8,
pub minor: u8,
pub patch: u8,
pub meta: Option<Meta>,
}

impl CrateVersion {
pub const LOCAL: Self = Self::parse(env!("CARGO_PKG_VERSION"));
}

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub enum Meta {
Rc(u8),
Alpha(u8),
Expand Down
1 change: 1 addition & 0 deletions crates/re_data_loader/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ default = []


[dependencies]
re_build_info.workspace = true
re_log_encoding = { workspace = true, features = ["decoder"] }
re_log_types.workspace = true
re_log.workspace = true
Expand Down
9 changes: 8 additions & 1 deletion crates/re_data_loader/src/load_file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,8 @@ pub(crate) fn prepare_store_info(
let app_id = re_log_types::ApplicationId(path.display().to_string());
let store_source = re_log_types::StoreSource::File { file_source };

let is_rrd = crate::SUPPORTED_RERUN_EXTENSIONS.contains(&extension(path).as_str());
let ext = extension(path);
let is_rrd = crate::SUPPORTED_RERUN_EXTENSIONS.contains(&ext.as_str());

(!is_rrd).then(|| {
LogMsg::SetStoreInfo(SetStoreInfo {
Expand All @@ -113,6 +114,12 @@ pub(crate) fn prepare_store_info(
is_official_example: false,
started: re_log_types::Time::now(),
store_source,
// NOTE: If this is a natively supported file, it will go through one of the
// builtin dataloaders, i.e. the local version.
// Otherwise, it will go through an arbitrary external loader, at which point we
// have no certainty what the version is.
store_version: crate::is_supported_file_extension(ext.as_str())
.then_some(re_build_info::CrateVersion::LOCAL),
},
})
})
Expand Down
9 changes: 9 additions & 0 deletions crates/re_data_ui/src/entity_db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ impl crate::DataUi for EntityDb {
is_official_example: _,
started,
store_source,
store_version,
} = store_info;

if let Some(cloned_from) = cloned_from {
Expand All @@ -60,6 +61,14 @@ impl crate::DataUi for EntityDb {
ui.label(store_source.to_string());
ui.end_row();

if let Some(store_version) = store_version {
re_ui.grid_left_hand_label(ui, "Source RRD version");
ui.label(store_version.to_string());
ui.end_row();
} else {
re_log::debug_once!("store version is undefined for this recording, this is a bug");
}

re_ui.grid_left_hand_label(ui, "Kind");
ui.label(store_id.kind.to_string());
ui.end_row();
Expand Down
9 changes: 9 additions & 0 deletions crates/re_data_ui/src/log_msg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ impl DataUi for SetStoreInfo {
started,
store_source,
is_official_example,
store_version,
} = info;

let re_ui = &ctx.re_ui;
Expand Down Expand Up @@ -77,6 +78,14 @@ impl DataUi for SetStoreInfo {
ui.label(format!("{store_source}"));
ui.end_row();

if let Some(store_version) = store_version {
re_ui.grid_left_hand_label(ui, "store_version:");
ui.label(format!("{store_version}"));
ui.end_row();
} else {
re_log::debug_once!("store version is undefined for this recording, this is a bug");
}

re_ui.grid_left_hand_label(ui, "is_official_example:");
ui.label(format!("{is_official_example}"));
ui.end_row();
Expand Down
1 change: 1 addition & 0 deletions crates/re_entity_db/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ serde = ["dep:serde", "dep:rmp-serde", "re_log_types/serde"]


[dependencies]
re_build_info.workspace = true
re_data_store.workspace = true
re_format.workspace = true
re_int_histogram.workspace = true
Expand Down
9 changes: 7 additions & 2 deletions crates/re_entity_db/examples/memory_usage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,13 @@ fn log_messages() {
fn encode_log_msg(log_msg: &LogMsg) -> Vec<u8> {
let mut bytes = vec![];
let encoding_options = re_log_encoding::EncodingOptions::COMPRESSED;
re_log_encoding::encoder::encode(encoding_options, std::iter::once(log_msg), &mut bytes)
.unwrap();
re_log_encoding::encoder::encode(
re_build_info::CrateVersion::LOCAL,
encoding_options,
std::iter::once(log_msg),
&mut bytes,
)
.unwrap();
bytes
}

Expand Down
1 change: 1 addition & 0 deletions crates/re_entity_db/src/store_bundle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ impl StoreBundle {
is_official_example: false,
started: re_log_types::Time::now(),
store_source: re_log_types::StoreSource::Other("viewer".to_owned()),
store_version: Some(re_build_info::CrateVersion::LOCAL),
},
});

Expand Down
8 changes: 7 additions & 1 deletion crates/re_log_encoding/benches/msg_encode_benchmark.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,13 @@ criterion_main!(benches);
fn encode_log_msgs(messages: &[LogMsg]) -> Vec<u8> {
let encoding_options = re_log_encoding::EncodingOptions::COMPRESSED;
let mut bytes = vec![];
re_log_encoding::encoder::encode(encoding_options, messages.iter(), &mut bytes).unwrap();
re_log_encoding::encoder::encode(
re_build_info::CrateVersion::LOCAL,
encoding_options,
messages.iter(),
&mut bytes,
)
.unwrap();
assert!(bytes.len() > messages.len());
bytes
}
Expand Down
38 changes: 28 additions & 10 deletions crates/re_log_encoding/src/decoder/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,23 +37,22 @@ fn warn_on_version_mismatch(
CrateVersion::from_bytes(encoded_version)
};

const LOCAL_VERSION: CrateVersion = CrateVersion::parse(env!("CARGO_PKG_VERSION"));

if encoded_version.is_compatible_with(LOCAL_VERSION) {
if encoded_version.is_compatible_with(CrateVersion::LOCAL) {
Ok(())
} else {
match version_policy {
VersionPolicy::Warn => {
re_log::warn_once!(
"Found log stream with Rerun version {encoded_version}, \
which is incompatible with the local Rerun version {LOCAL_VERSION}. \
Loading will try to continue, but might fail in subtle ways."
which is incompatible with the local Rerun version {}. \
Loading will try to continue, but might fail in subtle ways.",
CrateVersion::LOCAL,
);
Ok(())
}
VersionPolicy::Error => Err(DecodeError::IncompatibleRerunVersion {
file: encoded_version,
local: LOCAL_VERSION,
local: CrateVersion::LOCAL,
}),
}
}
Expand Down Expand Up @@ -109,7 +108,7 @@ pub fn decode_bytes(
pub fn read_options(
version_policy: VersionPolicy,
bytes: &[u8],
) -> Result<EncodingOptions, DecodeError> {
) -> Result<(CrateVersion, EncodingOptions), DecodeError> {
let mut read = std::io::Cursor::new(bytes);

let FileHeader {
Expand All @@ -130,10 +129,11 @@ pub fn read_options(
Serializer::MsgPack => {}
}

Ok(options)
Ok((CrateVersion::from_bytes(version), options))
}

pub struct Decoder<R: std::io::Read> {
version: CrateVersion,
compression: Compression,
read: R,
uncompressed: Vec<u8>, // scratch space
Expand All @@ -146,15 +146,24 @@ impl<R: std::io::Read> Decoder<R> {

let mut data = [0_u8; FileHeader::SIZE];
read.read_exact(&mut data).map_err(DecodeError::Read)?;
let compression = read_options(version_policy, &data)?.compression;

let (version, options) = read_options(version_policy, &data)?;
let compression = options.compression;

Ok(Self {
version,
compression,
read,
uncompressed: vec![],
compressed: vec![],
})
}

/// Returns the Rerun version that was used to encode the data in the first place.
#[inline]
pub fn version(&self) -> CrateVersion {
self.version
}
}

impl<R: std::io::Read> Iterator for Decoder<R> {
Expand Down Expand Up @@ -211,6 +220,12 @@ impl<R: std::io::Read> Iterator for Decoder<R> {

re_tracing::profile_scope!("MsgPack deser");
match rmp_serde::from_slice(&self.uncompressed[..uncompressed_len]) {
Ok(re_log_types::LogMsg::SetStoreInfo(mut msg)) => {
// Propagate the protocol version from the header into the `StoreInfo` so that all
// parts of the app can easily access it.
msg.info.store_version = Some(self.version());
Some(Ok(re_log_types::LogMsg::SetStoreInfo(msg)))
}
Ok(msg) => Some(Ok(msg)),
Err(err) => Some(Err(err.into())),
}
Expand All @@ -227,6 +242,8 @@ fn test_encode_decode() {
Time,
};

let rrd_version = CrateVersion::LOCAL;

let messages = vec![LogMsg::SetStoreInfo(SetStoreInfo {
row_id: RowId::new(),
info: StoreInfo {
Expand All @@ -239,6 +256,7 @@ fn test_encode_decode() {
rustc_version: String::new(),
llvm_version: String::new(),
},
store_version: Some(rrd_version),
},
})];

Expand All @@ -255,7 +273,7 @@ fn test_encode_decode() {

for options in options {
let mut file = vec![];
crate::encoder::encode(options, messages.iter(), &mut file).unwrap();
crate::encoder::encode(rrd_version, options, messages.iter(), &mut file).unwrap();

let decoded_messages = Decoder::new(VersionPolicy::Error, &mut file.as_slice())
.unwrap()
Expand Down
Loading
Loading