Automatically remap repeatedly remapped channels
If you replay a log multiple times and are remapping a channel
/foo on each run, this will now cascade the remaps so that on
the first replay you got
/foo -> /original/foo
and then on the next replay you get
/original/foo -> /original/original/foo
/foo -> /original/foo
and so on.
This is needed to handle logs where timestamp channels are not
NOT_LOGGED.
Change-Id: I158735709504ee1d3ebb7a9678c03bbb0a53ba5c
Signed-off-by: James Kuszmaul <jabukuszmaul+collab@gmail.com>
diff --git a/aos/events/logging/log_reader.h b/aos/events/logging/log_reader.h
index 9e44996..07cca48 100644
--- a/aos/events/logging/log_reader.h
+++ b/aos/events/logging/log_reader.h
@@ -156,18 +156,36 @@
void SetEndTime(std::string end_time);
void SetEndTime(realtime_clock::time_point end_time);
+ // Enum to use for indicating how RemapLoggedChannel behaves when there is
+ // already a channel with the remapped name (e.g., as may happen when
+ // replaying a logfile that was itself generated from replay).
+ enum class RemapConflict {
+ // LOG(FATAL) on conflicts in remappings.
+ kDisallow,
+ // If we run into a conflict, attempt to remap the channel we would be
+ // overriding (and continue to do so if remapping *that* channel also
+ // generates a conflict).
+ // This will mean that if we repeatedly replay a log, we will end up
+ // stacking more and more /original's on the start of the oldest version
+ // of the channels.
+ kCascade
+ };
+
// Causes the logger to publish the provided channel on a different name so
// that replayed applications can publish on the proper channel name without
// interference. This operates on raw channel names, without any node or
// application specific mappings.
- void RemapLoggedChannel(std::string_view name, std::string_view type,
- std::string_view add_prefix = "/original",
- std::string_view new_type = "");
+ void RemapLoggedChannel(
+ std::string_view name, std::string_view type,
+ std::string_view add_prefix = "/original", std::string_view new_type = "",
+ RemapConflict conflict_handling = RemapConflict::kCascade);
template <typename T>
- void RemapLoggedChannel(std::string_view name,
- std::string_view add_prefix = "/original",
- std::string_view new_type = "") {
- RemapLoggedChannel(name, T::GetFullyQualifiedName(), add_prefix, new_type);
+ void RemapLoggedChannel(
+ std::string_view name, std::string_view add_prefix = "/original",
+ std::string_view new_type = "",
+ RemapConflict conflict_handling = RemapConflict::kCascade) {
+ RemapLoggedChannel(name, T::GetFullyQualifiedName(), add_prefix, new_type,
+ conflict_handling);
}
// Remaps the provided channel, though this respects node mappings, and
@@ -179,16 +197,17 @@
// TODO(austin): If you have 2 nodes remapping something to the same channel,
// this doesn't handle that. No use cases exist yet for that, so it isn't
// being done yet.
- void RemapLoggedChannel(std::string_view name, std::string_view type,
- const Node *node,
- std::string_view add_prefix = "/original",
- std::string_view new_type = "");
+ void RemapLoggedChannel(
+ std::string_view name, std::string_view type, const Node *node,
+ std::string_view add_prefix = "/original", std::string_view new_type = "",
+ RemapConflict conflict_handling = RemapConflict::kCascade);
template <typename T>
- void RemapLoggedChannel(std::string_view name, const Node *node,
- std::string_view add_prefix = "/original",
- std::string_view new_type = "") {
+ void RemapLoggedChannel(
+ std::string_view name, const Node *node,
+ std::string_view add_prefix = "/original", std::string_view new_type = "",
+ RemapConflict conflict_handling = RemapConflict::kCascade) {
RemapLoggedChannel(name, T::GetFullyQualifiedName(), node, add_prefix,
- new_type);
+ new_type, conflict_handling);
}
template <typename T>