Skip to content
Open
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
32 changes: 0 additions & 32 deletions cpp/common/include/IpcMessage.h
Original file line number Diff line number Diff line change
Expand Up @@ -271,19 +271,6 @@ class IpcMessage {
}
}

// returns all the key-strings of param_str as a single 'delim' delimited string
std::string get_keys(const std::string& param_str, const char delim = '/')
{
std::string keys_str;
constexpr size_t string_size = 256;
keys_str.reserve(string_size);
if (this->doc_.FindMember(param_str.c_str()) == doc_.MemberEnd())
return "";
rapidjson::Value& params = this->doc_[param_str.c_str()];
get_keys_helper(params, delim, keys_str);
return keys_str;
}

//! Sets the nack message type with a reason parameter
void set_nack(const std::string& reason);

Expand Down Expand Up @@ -475,25 +462,6 @@ class IpcMessage {
//! Maps an internal message timestamp representation to an ISO8601 extended format string
std::string valid_msg_timestamp(boost::posix_time::ptime msg_timestamp);

// helper function to recursively append key-strings in 'value' to the 'result' variable
static void get_keys_helper(const rapidjson::Value& value, const char delim, std::string& result)
{
if (__builtin_expect(value.IsObject(), 1)) {
for (const auto& member : value.GetObject()) {
// Store the found key
result.append(member.name.GetString()) += delim;

// Look deeper inside this key's value
get_keys_helper(member.value, delim, result);
}
} else if (value.IsArray()) {
// Arrays don't have keys, but their elements (like child objects) might
for (const auto& item : value.GetArray()) {
get_keys_helper(item, delim, result);
}
}
}

//! Indicates if the message has a params block
bool has_params(void) const;

Expand Down
5 changes: 3 additions & 2 deletions cpp/frameProcessor/include/FrameProcessorController.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,9 @@ class FrameProcessorController : public IFrameCallback,
/** Configuration constant for executing setup of shared memory interface **/
static const std::string CONFIG_FR_SETUP;

/** current metadata hash-value **/
static const std::string METADATA_HASH;
/** key-strings for latest config and status timestamp **/
static const std::string CONFIG_TS_KEY;
static const std::string STATUS_TS_KEY;

/** Configuration constant for control socket endpoint **/
static const std::string CONFIG_CTRL_ENDPOINT;
Expand Down
27 changes: 27 additions & 0 deletions cpp/frameProcessor/include/FrameProcessorPlugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,31 @@ class FrameProcessorPlugin : public IFrameCallback, public OdinData::IVersionedO
void remove_callback(const std::string& name);
void remove_all_callbacks();
void notify_end_of_acquisition();
/** return the latest ts of config/status metadata for this plugin instance */
__attribute__((always_inline)) int64_t get_config_ts() const
{
return this->config_ts_;
}
__attribute__((always_inline)) int64_t get_status_ts() const
{
return this->status_ts_;
}

protected:
/** function to update the config time-stamp! */
__attribute__((always_inline)) void update_config_ts(void)
{
auto time_stamp_ms = std::chrono::time_point_cast<std::chrono::microseconds>(std::chrono::steady_clock::now());
auto val = std::chrono::duration_cast<std::chrono::microseconds>(time_stamp_ms.time_since_epoch());
this->config_ts_ = val.count();
}
/** function to update the status time-stamp! */
__attribute__((always_inline)) void update_status_ts(void)
{
auto time_stamp_ms = std::chrono::time_point_cast<std::chrono::microseconds>(std::chrono::steady_clock::now());
auto val = std::chrono::duration_cast<std::chrono::microseconds>(time_stamp_ms.time_since_epoch());
this->status_ts_ = val.count();
}
void push(boost::shared_ptr<Frame> frame);
void push(const std::string& plugin_name, boost::shared_ptr<Frame> frame);

Expand Down Expand Up @@ -242,6 +265,10 @@ class FrameProcessorPlugin : public IFrameCallback, public OdinData::IVersionedO
boost::mutex mutex_;
/** process_frame performance stats */
CallDuration process_duration_;
/** time-stamp to represent the version of config structure */
int64_t config_ts_;
/** time-stamp to represent the version of status structure */
int64_t status_ts_;
};

} /* namespace FrameProcessor */
Expand Down
4 changes: 3 additions & 1 deletion cpp/frameProcessor/src/FileWriterPlugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -366,11 +366,13 @@ void FileWriterPlugin::configure(OdinData::IpcMessage& config, OdinData::IpcMess
this->configure_dataset(dataset_name, dsetConfig, reply);
}
}
update_config_ts();
}

// Check to see if we are deleting all datasets
if (config.has_param(FileWriterPlugin::CONFIG_DELETE_DATASETS)) {
this->delete_datasets();
update_config_ts();
}

// Check to see if we are being told how many frames to write
Expand Down Expand Up @@ -878,7 +880,7 @@ void FileWriterPlugin::delete_datasets()
void FileWriterPlugin::status(OdinData::IpcMessage& status)
{
// Record the plugin's status items
std::string prefix = get_name() + '/';
const std::string prefix = get_name() + '/';
status.set_param(prefix + STATUS_WRITING, this->writing_);
status.set_param(prefix + STATUS_FRAMES_MAX, (int)this->current_acquisition_->frames_to_write_);
status.set_param(prefix + STATUS_FRAMES_WRITTEN, (int)this->current_acquisition_->frames_written_);
Expand Down
21 changes: 10 additions & 11 deletions cpp/frameProcessor/src/FrameProcessorController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ const std::string FrameProcessorController::CONFIG_VALUE = "value";

const std::string FrameProcessorController::COMMAND_KEY = "command";
const std::string FrameProcessorController::SUPPORTED_KEY = "supported";
const std::string FrameProcessorController::METADATA_HASH = "metadata_hash";
const std::string FrameProcessorController::CONFIG_TS_KEY = "config_ts";
const std::string FrameProcessorController::STATUS_TS_KEY = "status_ts";

const int FrameProcessorController::META_TX_HWM = 10000;

Expand Down Expand Up @@ -294,11 +295,6 @@ void FrameProcessorController::provideStatus(OdinData::IpcMessage& reply, bool m
sharedMemController_->status(reply);
}

// returns all key strings in "params" as a '/' delimited string
std::string param_keys = reply.get_keys("params", '/');
size_t hash = std::hash<std::string> {}(param_keys);
reply.set_param(FrameProcessorController::METADATA_HASH, hash);

std::map<std::string, boost::shared_ptr<FrameProcessorPlugin>>::iterator iter;
if (metadata) {
for (iter = plugins_.begin(); iter != plugins_.end(); ++iter) {
Expand All @@ -307,11 +303,14 @@ void FrameProcessorController::provideStatus(OdinData::IpcMessage& reply, bool m
}
}

int64_t latest_ts = -1;
// Loop over plugins, list names and request status from each
for (iter = plugins_.begin(); iter != plugins_.end(); ++iter) {
reply.set_param("plugins/names[]", iter->first);
// Request status for the plugin
iter->second->status(reply);
// Check for the latest timestamp
latest_ts = std::max(latest_ts, iter->second->get_status_ts());
// Add performance statistics
iter->second->add_performance_stats(reply);
// Read error level
Expand All @@ -321,6 +320,8 @@ void FrameProcessorController::provideStatus(OdinData::IpcMessage& reply, bool m
std::vector<std::string> plugin_warnings = iter->second->get_warnings();
warning_messages.insert(warning_messages.end(), plugin_warnings.begin(), plugin_warnings.end());
}
reply.set_param(FrameProcessorController::STATUS_TS_KEY, latest_ts);

std::vector<std::string>::iterator error_iter;
for (error_iter = error_messages.begin(); error_iter != error_messages.end(); ++error_iter) {
reply.set_param("error[]", *error_iter);
Expand Down Expand Up @@ -535,16 +536,14 @@ void FrameProcessorController::requestConfiguration(OdinData::IpcMessage& reply,
reply.set_param(fr_cnxn_str + FrameProcessorController::CONFIG_FR_RELEASE, frReleaseEndpoint_);

// Loop over plugins and request current configuration from each
int64_t latest_ts = -1;
std::map<std::string, boost::shared_ptr<FrameProcessorPlugin>>::iterator iter;
for (iter = plugins_.begin(); iter != plugins_.end(); ++iter) {
reply.set_param("plugins/names[]", iter->first);
iter->second->requestConfiguration(reply);
latest_ts = std::max(latest_ts, iter->second->get_config_ts());
}

// returns all key strings in "params" as a '/' delimited string
std::string param_keys = reply.get_keys("params", '/');
size_t hash = std::hash<std::string> {}(param_keys);
reply.set_param(FrameProcessorController::METADATA_HASH, hash);
reply.set_param(FrameProcessorController::CONFIG_TS_KEY, latest_ts);

if (metadata) {
for (iter = plugins_.begin(); iter != plugins_.end(); ++iter) {
Expand Down
2 changes: 2 additions & 0 deletions cpp/frameProcessor/src/FrameProcessorPlugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ FrameProcessorPlugin::FrameProcessorPlugin() :
{
OdinData::configure_logging_mdc(OdinData::app_path.c_str());
logger_ = log4cxx::Logger::getLogger("FP.FrameProcessorPlugin");
update_config_ts();
update_status_ts();
}

/**
Expand Down
1 change: 1 addition & 0 deletions cpp/frameProcessor/src/ParameterAdjustmentPlugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ void ParameterAdjustmentPlugin::configure(OdinData::IpcMessage& config, OdinData
parameter_adjustments_.clear();
parameter_inputs_.clear();
}
update_config_ts();
}
} catch (std::runtime_error& e) {
std::stringstream ss;
Expand Down
13 changes: 13 additions & 0 deletions cpp/frameProcessor/test/FileWriterPluginTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -151,4 +151,17 @@ BOOST_AUTO_TEST_CASE(FileWriterPluginZeroFrames)
}
}

BOOST_AUTO_TEST_CASE(FileWriterPluginMetadataTimestampUpdate)
{
FrameProcessor::FileWriterPlugin fwp;
int64_t first_ts = fwp.get_config_ts();
OdinData::IpcMessage cfg;
OdinData::IpcMessage reply;
fwp.set_name("hdf");
cfg.set_param<std::string>(FrameProcessor::FileWriterPlugin::CONFIG_DATASET, "new_dataset");
fwp.configure(cfg, reply);
int64_t second_ts = fwp.get_config_ts();
BOOST_CHECK(second_ts > first_ts);
}

BOOST_AUTO_TEST_SUITE_END();
12 changes: 12 additions & 0 deletions cpp/frameProcessor/test/ParameterAdjustmentPluginTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,4 +106,16 @@ BOOST_AUTO_TEST_CASE(AdjustExistingParameter)
BOOST_CHECK_EQUAL(14, frame->get_meta_data().get_parameter<uint64_t>("UID"));
}

BOOST_AUTO_TEST_CASE(ValidateMetadataTimestampUpdate)
{
FrameProcessor::ParameterAdjustmentPlugin plugin;
OdinData::IpcMessage reply;
OdinData::IpcMessage cfg;
int64_t first_ts = plugin.get_config_ts();
cfg.set_param(FrameProcessor::PARAMETER_NAME_CONFIG + "/UID/" + FrameProcessor::PARAMETER_ADJUSTMENT_CONFIG, 4);
plugin.configure(cfg, reply);
int64_t second_ts = plugin.get_config_ts();
BOOST_CHECK(second_ts > first_ts);
}

BOOST_AUTO_TEST_SUITE_END(); // ParameterAdjustmentPluginUnitTest
27 changes: 0 additions & 27 deletions cpp/frameReceiver/test/IpcMessageUnitTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -383,31 +383,4 @@ BOOST_AUTO_TEST_CASE(TestIpcMessageCreationSpeed)
<< rate << " Hz"
);
}

BOOST_AUTO_TEST_CASE(IpcMessageGetKeys)
{
const char* json_str = "{ \"msg_type\":\"cmd\","
" \"msg_val\":\"status\","
" \"timestamp\" : \"2026-05-09T12:10:01.123456\","
" \"status\" : true,"
" \"params\" : {"
" \"param1\" : \"values\","
" \"param2\" : 274,"
" \"info\": {"
" \"phoneNumber\": 2026,"
" \"state\": true,"
" \"name\":{"
" \"first\": \"odin\","
" \"last\": \"data\""
" },"
" \"dob\": 2011"
" }"
" }"
"}";
OdinData::IpcMessage test_msg(json_str, true);
BOOST_CHECK(test_msg.is_valid() == true);
std::string keys_list = test_msg.get_keys("params");
BOOST_CHECK(keys_list == "param1/param2/info/phoneNumber/state/name/first/last/dob/");
}

BOOST_AUTO_TEST_SUITE_END();