Support for metric list versions

including subscriptions to new metric values and cancellation of subscriptions if metrics are removed

Change-Id: I967a9c1847618aa5398f247c7e2fd71de2ecc46b
This commit is contained in:
Geir Horn 2024-01-27 18:30:53 +01:00
parent 36af1a2605
commit d0ad28446b
3 changed files with 57 additions and 9 deletions

View File

@ -7,11 +7,12 @@
"/home/GHo/Documents/Code/CxxOpts/include", "/home/GHo/Documents/Code/CxxOpts/include",
"/opt/AMPL/amplapi/include/", "/opt/AMPL/amplapi/include/",
"${workspaceFolder}/**", "${workspaceFolder}/**",
"/usr/lib/gcc/x86_64-redhat-linux/13/../../../../include/c++/13" "/usr/lib/gcc/x86_64-redhat-linux/13/../../../../include/c++/13",
"/home/GHo/Documents/Code/Theron++"
], ],
"defines": [], "defines": [],
"cStandard": "c23", "cStandard": "c23",
"intelliSenseMode": "${default}", "intelliSenseMode": "linux-gcc-x64",
"compilerPath": "/usr/bin/g++", "compilerPath": "/usr/bin/g++",
"compilerArgs": [ "compilerArgs": [
"-std=c++23", "-std=c++23",

View File

@ -38,24 +38,59 @@ namespace NebulOuS
// metric values must be updated before the complete set of metrics will be // metric values must be updated before the complete set of metrics will be
// used for finding a better configuration for the application's execution // used for finding a better configuration for the application's execution
// context given by the metric values. // context given by the metric values.
//
// The message is just considered if the version number of the message is larger
// than the version of the current set of metrics. The complicating factor is
// to deal with metrics that have changed in the case the metric version is
// increased. Then new metrics must be subscribed, deleted metrics must be
// unsubscribed, and values for kept metrics must be kept.
void MetricUpdater::AddMetricSubscription( const MetricTopic & TheMetrics, void MetricUpdater::AddMetricSubscription( const MetricTopic & TheMetrics,
const Address OptimiserController ) const Address OptimiserController )
{ {
if( TheMetrics.is_object() && if( TheMetrics.is_object() &&
TheMetrics.at( NebulOuS::MetricList ).is_array() ) TheMetrics.at( NebulOuS::MetricList ).is_array() &&
(MetricsVersion < TheMetrics.at( MetricVersionCounter ).get<long int>()) )
{ {
// The first step is to try inserting the metrics into the metric value map
// and if this is successful, a subscription is created for the publisher
// of this metric value. The metric names are recorded since some of them
// may correspond to known metrics, some of them may correspond to metrics
// that are new.
std::set< std::string > MetricNames;
for (auto & MetricRecord : TheMetrics.at( NebulOuS::MetricList ) ) for (auto & MetricRecord : TheMetrics.at( NebulOuS::MetricList ) )
{ {
auto [ MetricRecordPointer, NewMetric ] = MetricValues.try_emplace( auto [ MetricRecordPointer, MetricAdded ] = MetricValues.try_emplace(
MetricRecord.at( NebulOuS::MetricName ), JSON() ); MetricRecord.at( NebulOuS::MetricName ), JSON() );
if( NewMetric ) MetricNames.insert( MetricRecordPointer->first );
if( MetricAdded )
Send( Theron::AMQ::NetworkLayer::TopicSubscription( Send( Theron::AMQ::NetworkLayer::TopicSubscription(
Theron::AMQ::NetworkLayer::TopicSubscription::Action::Subscription, Theron::AMQ::NetworkLayer::TopicSubscription::Action::Subscription,
std::string( MetricValueRootString ) + MetricRecordPointer->first ), std::string( MetricValueRootString ) + MetricRecordPointer->first ),
Theron::AMQ::Network::GetAddress( Theron::Network::Layer::Session) ); //Theron::AMQ::Network::GetAddress( Theron::Network::Layer::Session) );
GetSessionLayerAddress() );
} }
// There could be some metric value records that were defined by the previous
// metrics defined, but missing from the new metric set. If this is the case,
// the metric value records for the missing metrics should be unsubcribed
// and their metric records removed.
for( const auto & TheMetric : std::views::keys( MetricValues ) )
if( !MetricName.contains( TheMetric ) )
{
Send( Theron::AMQ::NetworkLayer::TopicSubscription(
Theron::AMQ::NetworkLayer::TopicSubscription::Action::CloseSubscription,
std::string( MetricValueRootString ) + TheMetric ),
//Theron::AMQ::Network::GetAddress( Theron::Network::Layer::Session) );
GetSessionLayerAddress() );
MetricValues.erase( TheMetric );
}
} }
else else
{ {
@ -184,7 +219,8 @@ MetricUpdater::MetricUpdater( const std::string UpdaterName,
: Actor( UpdaterName ), : Actor( UpdaterName ),
StandardFallbackHandler( Actor::GetAddress().AsString() ), StandardFallbackHandler( Actor::GetAddress().AsString() ),
NetworkingActor( Actor::GetAddress().AsString() ), NetworkingActor( Actor::GetAddress().AsString() ),
MetricValues(), ValidityTime(0), TheSolverManager( ManagerOfSolvers ) MetricValues(), ValidityTime(0), TheSolverManager( ManagerOfSolvers ),
MetricsVersion(-1)
{ {
RegisterHandler( this, &MetricUpdater::AddMetricSubscription ); RegisterHandler( this, &MetricUpdater::AddMetricSubscription );
RegisterHandler( this, &MetricUpdater::UpdateMetricValue ); RegisterHandler( this, &MetricUpdater::UpdateMetricValue );

View File

@ -95,8 +95,9 @@ constexpr std::string_view MetricSubscriptions
// https://158.39.75.54/projects/nebulous-collaboration-hub/wiki/slo-severity-based-violation-detector // https://158.39.75.54/projects/nebulous-collaboration-hub/wiki/slo-severity-based-violation-detector
// where the name of the metric is defined under as sub-key. // where the name of the metric is defined under as sub-key.
constexpr std::string_view MetricList = "metric_list"; constexpr std::string_view MetricList = "metric_list",
constexpr std::string_view MetricName = "name"; MetricName = "name",
MetricVersionCounter = "version";
// The metric value messages will be published on different topics and to // The metric value messages will be published on different topics and to
// check if an inbound message is from a metric value topic, it is necessary // check if an inbound message is from a metric value topic, it is necessary
@ -210,6 +211,16 @@ private:
virtual ~MetricTopic() = default; virtual ~MetricTopic() = default;
}; };
// The metric definition message "Event type III" of the EMS is sent every
// 60 seconds in order to inform new components or crashed components about
// the metrics. The version number of the message is a counter that indicates
// if the set of metrics has changed. Thus the message should be ignored
// as long as the version number stays the same. The version number of the
// current set of metrics is therefore cached to avoid redefining the
// metrics.
long int MetricsVersion;
// The handler for this message will check each attribute value of the // The handler for this message will check each attribute value of the
// received JSON struct, and those not already existing in the metric // received JSON struct, and those not already existing in the metric
// value map be added and a subscription made for the published // value map be added and a subscription made for the published