Merge "Application ID in all messages and improved SLO message handling"
This commit is contained in:
commit
7584bef98e
2
.vscode/c_cpp_properties.json
vendored
2
.vscode/c_cpp_properties.json
vendored
@ -13,7 +13,7 @@
|
|||||||
"defines": [],
|
"defines": [],
|
||||||
"cStandard": "c23",
|
"cStandard": "c23",
|
||||||
"intelliSenseMode": "linux-gcc-x64",
|
"intelliSenseMode": "linux-gcc-x64",
|
||||||
"compilerPath": "/usr/bin/g++",
|
"compilerPath": "/usr/lib64/ccache/g++",
|
||||||
"compilerArgs": [
|
"compilerArgs": [
|
||||||
"-std=c++23",
|
"-std=c++23",
|
||||||
"-I/usr/include/",
|
"-I/usr/include/",
|
||||||
|
@ -156,6 +156,10 @@ void AMPLSolver::SetAMPLParameter( const std::string & ParameterName,
|
|||||||
void AMPLSolver::DefineProblem(const Solver::OptimisationProblem & TheProblem,
|
void AMPLSolver::DefineProblem(const Solver::OptimisationProblem & TheProblem,
|
||||||
const Address TheOracle)
|
const Address TheOracle)
|
||||||
{
|
{
|
||||||
|
Theron::ConsoleOutput Output;
|
||||||
|
Output << "AMPL Solver: Optimisation problem received " << std::endl
|
||||||
|
<< TheProblem.dump(2) << std::endl;
|
||||||
|
|
||||||
// First storing the AMPL problem file from its definition in the message
|
// First storing the AMPL problem file from its definition in the message
|
||||||
// and read the file back to the AMPL interpreter.
|
// and read the file back to the AMPL interpreter.
|
||||||
|
|
||||||
@ -230,6 +234,11 @@ void AMPLSolver::DataFileUpdate( const DataFileMessage & TheDataFile,
|
|||||||
void AMPLSolver::SolveProblem(
|
void AMPLSolver::SolveProblem(
|
||||||
const ApplicationExecutionContext & TheContext, const Address TheRequester )
|
const ApplicationExecutionContext & TheContext, const Address TheRequester )
|
||||||
{
|
{
|
||||||
|
Theron::ConsoleOutput Output;
|
||||||
|
|
||||||
|
Output << "AMPL Solver: Application Execution Context received. Problem Undefined = " << ProblemUndefined << std::endl
|
||||||
|
<< TheContext.dump(2) << std::endl;
|
||||||
|
|
||||||
// There is nothing to do if the application model is missing.
|
// There is nothing to do if the application model is missing.
|
||||||
|
|
||||||
if( ProblemUndefined ) return;
|
if( ProblemUndefined ) return;
|
||||||
@ -339,6 +348,8 @@ void AMPLSolver::SolveProblem(
|
|||||||
OptimisationGoal, ObjectiveValues, VariableValues,
|
OptimisationGoal, ObjectiveValues, VariableValues,
|
||||||
DeploymentFlagSet
|
DeploymentFlagSet
|
||||||
), TheRequester );
|
), TheRequester );
|
||||||
|
|
||||||
|
Output << "Solver found a solution" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
@ -169,31 +169,25 @@ void MetricUpdater::UpdateMetricValue(
|
|||||||
void MetricUpdater::SLOViolationHandler(
|
void MetricUpdater::SLOViolationHandler(
|
||||||
const SLOViolation & SeverityMessage, const Address TheSLOTopic )
|
const SLOViolation & SeverityMessage, const Address TheSLOTopic )
|
||||||
{
|
{
|
||||||
// The application execution context is constructed first
|
Theron::ConsoleOutput Output;
|
||||||
// as it represents the name and the current values of the recorded
|
Output << "Metric Updater: SLO violation received " << std::endl
|
||||||
// metrics.
|
<< SeverityMessage.dump(2) << std::endl;
|
||||||
|
|
||||||
Solver::MetricValueType TheApplicationExecutionContext;
|
|
||||||
|
|
||||||
for( const auto & [ MetricName, MetricValue ] : MetricValues )
|
|
||||||
if( !MetricValue.is_null() )
|
|
||||||
TheApplicationExecutionContext.emplace( MetricName, MetricValue );
|
|
||||||
|
|
||||||
// The application context can then be sent to the solution manager
|
// The application context can then be sent to the solution manager
|
||||||
// using the corresponding message, and the time stamp of the severity
|
// using the application execution context message provided that none of
|
||||||
// message provided that the size of the execution context equals the
|
// metric values are null indicating that no value has been received (yet)
|
||||||
// number of metric values. It will be different if any of the metric
|
// Thus, only if all metrics have values will the message be sent.
|
||||||
// values has not been updated, and in this case the application execution
|
|
||||||
// context is invalid and cannot be used for optimisation and the
|
|
||||||
// SLO violation event will just be ignored. Finally, the flag indicating
|
|
||||||
// that the corresponding solution found for this application execution
|
|
||||||
// context should actually be enacted and deployed.
|
|
||||||
|
|
||||||
if( TheApplicationExecutionContext.size() == MetricValues.size() )
|
if( !MetricValues.empty() &&
|
||||||
|
std::ranges::none_of( MetricValues,
|
||||||
|
[](const auto & MetricRecord){ return MetricRecord.second.is_null(); } ))
|
||||||
Send( Solver::ApplicationExecutionContext(
|
Send( Solver::ApplicationExecutionContext(
|
||||||
SeverityMessage.at( NebulOuS::TimePoint ).get< Solver::TimePointType >(),
|
SeverityMessage.at( NebulOuS::TimePoint ).get< Solver::TimePointType >(),
|
||||||
TheApplicationExecutionContext, true
|
MetricValues, true
|
||||||
), TheSolverManager );
|
), TheSolverManager );
|
||||||
|
else
|
||||||
|
Output << "... failed to forward the application execution context (size: "
|
||||||
|
<< MetricValues.size() << ")" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
|
@ -141,7 +141,7 @@ int main( int NumberOfCLIOptions, char ** CLIOptionStrings )
|
|||||||
cxxopts::value<std::string>()->default_value("NebulOuS::Solver") )
|
cxxopts::value<std::string>()->default_value("NebulOuS::Solver") )
|
||||||
("P,Port", "TCP port on AMQ Broker",
|
("P,Port", "TCP port on AMQ Broker",
|
||||||
cxxopts::value<unsigned int>()->default_value("5672") )
|
cxxopts::value<unsigned int>()->default_value("5672") )
|
||||||
("S,Solver", "Solver to use, devault Couenne",
|
("S,Solver", "Solver to use, default Couenne",
|
||||||
cxxopts::value<std::string>()->default_value("couenne") )
|
cxxopts::value<std::string>()->default_value("couenne") )
|
||||||
("U,User", "The user name used for the AMQ Broker connection",
|
("U,User", "The user name used for the AMQ Broker connection",
|
||||||
cxxopts::value<std::string>()->default_value("admin") )
|
cxxopts::value<std::string>()->default_value("admin") )
|
||||||
@ -257,11 +257,13 @@ int main( int NumberOfCLIOptions, char ** CLIOptionStrings )
|
|||||||
// The application identifier must also be provided in every message to
|
// The application identifier must also be provided in every message to
|
||||||
// allow other receivers to filter on this.
|
// allow other receivers to filter on this.
|
||||||
|
|
||||||
virtual proton::message::property_map
|
virtual proton::message::property_map MessageProperties(
|
||||||
MessageProperties( void ) const override
|
const proton::message::property_map & CurrentProperties
|
||||||
|
= proton::message::property_map() ) const override
|
||||||
{
|
{
|
||||||
proton::message::property_map TheProperties(
|
proton::message::property_map TheProperties(
|
||||||
Theron::AMQ::NetworkLayer::AMQProperties::MessageProperties() );
|
Theron::AMQ::NetworkLayer::AMQProperties::MessageProperties(
|
||||||
|
CurrentProperties ));
|
||||||
|
|
||||||
TheProperties.put( "application", ApplicationID );
|
TheProperties.put( "application", ApplicationID );
|
||||||
|
|
||||||
@ -288,7 +290,7 @@ int main( int NumberOfCLIOptions, char ** CLIOptionStrings )
|
|||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// The AMQ communication is managed by the standard communication actors of
|
// The AMQ communication is managed by the standard communication actors of
|
||||||
// the Theron++ Actor framewokr. Thus, it is just a matter of starting the
|
// the Theron++ Actor framework. Thus, it is just a matter of starting the
|
||||||
// endpoint actors with the given command line parameters.
|
// endpoint actors with the given command line parameters.
|
||||||
//
|
//
|
||||||
// The network endpoint takes the endpoint name as the first argument, then
|
// The network endpoint takes the endpoint name as the first argument, then
|
||||||
|
Loading…
Reference in New Issue
Block a user