Correcting the mess caused by Gerrit
Change-Id: If80c41555a93773a76f927036e88c3c6229c031f
This commit is contained in:
parent
58ec992fe3
commit
2bf9748509
@ -247,7 +247,8 @@ void AMPLSolver::SolveProblem(
|
|||||||
{
|
{
|
||||||
Theron::ConsoleOutput Output;
|
Theron::ConsoleOutput Output;
|
||||||
|
|
||||||
Output << "AMPL Solver: Application Execution Context received. Problem Undefined = " << ProblemUndefined << std::endl
|
Output << "AMPL Solver: Application Execution Context received. Problem Undefined = "
|
||||||
|
<< std::boolalpha << ProblemUndefined << std::endl
|
||||||
<< TheContext.dump(2) << 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.
|
||||||
|
@ -11,7 +11,7 @@ RUN mkdir -p /solver
|
|||||||
WORKDIR /solver
|
WORKDIR /solver
|
||||||
|
|
||||||
# Development framework, dependencies
|
# Development framework, dependencies
|
||||||
RUN dnf --assumeyes install gcc-c++-13.2.1-7.fc39 make-1:4.4.1-2.fc39 git-core-2.44.0-1.fc39 boost-devel-1.81.0-8.fc39 ccache-4.8.2-2.fc39 qpid-proton-cpp-devel-0.38.0-4.fc39 json-c-0.17-1.fc39 json-devel-3.11.2-3.fc39 json-glib-1.8.0-1.fc39 jsoncpp-1.9.5-5.fc39 jsoncpp-devel-1.9.5-5.fc39 coin-or-Couenne-0.5.8-12.fc39 wget-1.21.3-7.fc39 && \
|
RUN dnf --assumeyes install gcc-c++-13.2.1-7.fc39 make-1:4.4.1-2.fc39 git-core-2.45.0-1.fc39 boost-devel-1.81.0-8.fc39 ccache-4.8.2-2.fc39 qpid-proton-cpp-devel-0.38.0-4.fc39 json-c-0.17-1.fc39 json-devel-3.11.2-3.fc39 json-glib-1.8.0-1.fc39 jsoncpp-1.9.5-5.fc39 jsoncpp-devel-1.9.5-5.fc39 coin-or-Couenne-0.5.8-12.fc39 wget-1.21.3-7.fc39 && \
|
||||||
dnf clean all && \
|
dnf clean all && \
|
||||||
git clone https://github.com/jarro2783/cxxopts.git CxxOpts && \
|
git clone https://github.com/jarro2783/cxxopts.git CxxOpts && \
|
||||||
git clone https://github.com/GeirHo/TheronPlusPlus.git Theron++ && \
|
git clone https://github.com/GeirHo/TheronPlusPlus.git Theron++ && \
|
||||||
|
@ -59,16 +59,16 @@ void MetricUpdater::AddMetricSubscription(
|
|||||||
|
|
||||||
TheMetricNames.insert( MetricRecordPointer->first );
|
TheMetricNames.insert( MetricRecordPointer->first );
|
||||||
|
|
||||||
|
// If a new metric was added, a subscription will be set up for this
|
||||||
|
// new metric, and the flag indicating that values have been received
|
||||||
|
// for all metrics will be reset.
|
||||||
|
|
||||||
if( MetricAdded )
|
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( MetricValueUpdate::MetricValueRootString )
|
std::string( MetricValueUpdate::MetricValueRootString )
|
||||||
+ MetricRecordPointer->first ),
|
+ MetricRecordPointer->first ),
|
||||||
GetSessionLayerAddress() );
|
GetSessionLayerAddress() );
|
||||||
|
|
||||||
AllMetricValuesSet = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// There could be some metric value records that were defined by the
|
// There could be some metric value records that were defined by the
|
||||||
@ -86,6 +86,16 @@ void MetricUpdater::AddMetricSubscription(
|
|||||||
|
|
||||||
MetricValues.erase( TheMetric );
|
MetricValues.erase( TheMetric );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Finally the number of metrics that does not yet have a value is counted
|
||||||
|
// to ensure that these must be received before the application context
|
||||||
|
// can be forwarded to the solver manager.
|
||||||
|
|
||||||
|
if( MetricValues.empty() )
|
||||||
|
UnsetMetrics = 1;
|
||||||
|
else
|
||||||
|
UnsetMetrics = std::ranges::count_if( std::views::values( MetricValues ),
|
||||||
|
[](const auto & MetricValue){ return MetricValue.is_null(); } );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -101,6 +111,10 @@ void MetricUpdater::AddMetricSubscription(
|
|||||||
|
|
||||||
throw std::invalid_argument( ErrorMessage.str() );
|
throw std::invalid_argument( ErrorMessage.str() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Theron::ConsoleOutput Output;
|
||||||
|
Output << "Received metric subscription request: " << std::endl
|
||||||
|
<< MetricDefinitions.dump(2) << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The metric update value is received whenever any of subscribed forecasters
|
// The metric update value is received whenever any of subscribed forecasters
|
||||||
@ -132,6 +146,12 @@ void MetricUpdater::AddMetricSubscription(
|
|||||||
void MetricUpdater::UpdateMetricValue(
|
void MetricUpdater::UpdateMetricValue(
|
||||||
const MetricValueUpdate & TheMetricValue, const Address TheMetricTopic)
|
const MetricValueUpdate & TheMetricValue, const Address TheMetricTopic)
|
||||||
{
|
{
|
||||||
|
Theron::ConsoleOutput Output;
|
||||||
|
|
||||||
|
Output << "Metric value received: " << std::endl
|
||||||
|
<< " Topic: " << TheMetricTopic.AsString() << std::endl
|
||||||
|
<< TheMetricValue.dump(2) << std::endl;
|
||||||
|
|
||||||
Theron::AMQ::TopicName TheTopic
|
Theron::AMQ::TopicName TheTopic
|
||||||
= TheMetricTopic.AsString().erase( 0,
|
= TheMetricTopic.AsString().erase( 0,
|
||||||
MetricValueUpdate::MetricValueRootString.size() );
|
MetricValueUpdate::MetricValueRootString.size() );
|
||||||
@ -144,6 +164,17 @@ void MetricUpdater::UpdateMetricValue(
|
|||||||
ValidityTime = std::max( ValidityTime,
|
ValidityTime = std::max( ValidityTime,
|
||||||
TheMetricValue.at(
|
TheMetricValue.at(
|
||||||
MetricValueUpdate::Keys::TimePoint ).get< Solver::TimePointType >() );
|
MetricValueUpdate::Keys::TimePoint ).get< Solver::TimePointType >() );
|
||||||
|
|
||||||
|
if( UnsetMetrics )
|
||||||
|
UnsetMetrics = std::ranges::count_if( std::views::values( MetricValues ),
|
||||||
|
[](const auto & MetricValue){ return MetricValue.is_null(); } );
|
||||||
|
|
||||||
|
Output << "Metric " << TheTopic << " has new value "
|
||||||
|
<< MetricValues.at( TheTopic ) << std::endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Output << TheTopic << " is not a known metric and ignored " << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -202,6 +233,11 @@ MetricUpdater::ApplicationLifecycle::operator State() const
|
|||||||
// message will just be ignored. In order to avoid the scan over all metrics
|
// message will just be ignored. In order to avoid the scan over all metrics
|
||||||
// to see if they are set, a boolean flag will be used and set once all metrics
|
// to see if they are set, a boolean flag will be used and set once all metrics
|
||||||
// have values. Then future scans will be avoided.
|
// have values. Then future scans will be avoided.
|
||||||
|
// The message will be ignored if not all metric values have been received
|
||||||
|
// or if there are no metric values defined. In both cases the SLO violation
|
||||||
|
// message will just be ignored. In order to avoid the scan over all metrics
|
||||||
|
// to see if they are set, a boolean flag will be used and set once all metrics
|
||||||
|
// have values. Then future scans will be avoided.
|
||||||
|
|
||||||
void MetricUpdater::SLOViolationHandler(
|
void MetricUpdater::SLOViolationHandler(
|
||||||
const SLOViolation & SeverityMessage, const Address TheSLOTopic )
|
const SLOViolation & SeverityMessage, const Address TheSLOTopic )
|
||||||
@ -211,23 +247,29 @@ void MetricUpdater::SLOViolationHandler(
|
|||||||
<< SeverityMessage.dump(2) << std::endl;
|
<< SeverityMessage.dump(2) << std::endl;
|
||||||
|
|
||||||
if(( ApplicationState == ApplicationLifecycle::State::Running ) &&
|
if(( ApplicationState == ApplicationLifecycle::State::Running ) &&
|
||||||
( AllMetricValuesSet ||
|
( UnsetMetrics == 0 ) )
|
||||||
(!MetricValues.empty() &&
|
|
||||||
std::ranges::none_of( std::views::values( MetricValues ),
|
|
||||||
[](const auto & MetricValue){ return MetricValue.is_null(); } ))) )
|
|
||||||
{
|
{
|
||||||
Send( Solver::ApplicationExecutionContext(
|
Send( Solver::ApplicationExecutionContext(
|
||||||
SeverityMessage.at(
|
SeverityMessage.at(
|
||||||
MetricValueUpdate::Keys::TimePoint ).get< Solver::TimePointType >(),
|
MetricValueUpdate::Keys::TimePoint ).get< Solver::TimePointType >(),
|
||||||
MetricValues, true
|
MetricValues, true
|
||||||
), TheSolverManager );
|
), TheSolverManager );
|
||||||
|
|
||||||
AllMetricValuesSet = true;
|
|
||||||
ApplicationState = ApplicationLifecycle::State::Deploying;
|
ApplicationState = ApplicationLifecycle::State::Deploying;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
Output << "... failed to forward the application execution context (size: "
|
Output << "... failed to forward the application execution context (size: "
|
||||||
<< MetricValues.size() << ")" << std::endl;
|
<< MetricValues.size() << "," << " Unset: " << UnsetMetrics
|
||||||
|
<< ")" << std::endl;
|
||||||
|
|
||||||
|
if( MetricValues.empty() )
|
||||||
|
Output << "The Metric Value map is empty! " << std::endl;
|
||||||
|
else
|
||||||
|
for( auto & MetricRecord : MetricValues )
|
||||||
|
Output << MetricRecord.first << " with value "
|
||||||
|
<< MetricRecord.second.dump(2) << " end " << std::endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
@ -250,14 +292,14 @@ 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), AllMetricValuesSet(false),
|
MetricValues(), ValidityTime(0), UnsetMetrics(1),
|
||||||
ApplicationState( ApplicationLifecycle::State::New ),
|
ApplicationState( ApplicationLifecycle::State::New ),
|
||||||
TheSolverManager( ManagerOfSolvers )
|
TheSolverManager( ManagerOfSolvers )
|
||||||
{
|
{
|
||||||
RegisterHandler( this, &MetricUpdater::AddMetricSubscription );
|
RegisterHandler( this, &MetricUpdater::AddMetricSubscription );
|
||||||
RegisterHandler( this, &MetricUpdater::UpdateMetricValue );
|
RegisterHandler( this, &MetricUpdater::UpdateMetricValue );
|
||||||
RegisterHandler( this, &MetricUpdater::SLOViolationHandler );
|
|
||||||
RegisterHandler( this, &MetricUpdater::LifecycleHandler );
|
RegisterHandler( this, &MetricUpdater::LifecycleHandler );
|
||||||
|
RegisterHandler( this, &MetricUpdater::SLOViolationHandler );
|
||||||
|
|
||||||
Send( Theron::AMQ::NetworkLayer::TopicSubscription(
|
Send( Theron::AMQ::NetworkLayer::TopicSubscription(
|
||||||
Theron::AMQ::NetworkLayer::TopicSubscription::Action::Subscription,
|
Theron::AMQ::NetworkLayer::TopicSubscription::Action::Subscription,
|
||||||
|
@ -110,14 +110,14 @@ private:
|
|||||||
|
|
||||||
Solver::TimePointType ValidityTime;
|
Solver::TimePointType ValidityTime;
|
||||||
|
|
||||||
// When an SLO violation message is received the current vector of metric
|
// The metric context is not complete before at least one value has been
|
||||||
// values should be sent as an application execution context (message) to the
|
// received for each metric. It is therefore a counter keeping track of
|
||||||
// Solution Manager actor that will invoke a solver to find the optimal
|
// metric values that are defined, but has not yet seen their first value
|
||||||
// configuration for this configuration. The Metric Updater must therefore
|
// update. An SLO violation message will only result in the triggering of
|
||||||
// know the address of the Soler Manager, and this must be passed to
|
// a serch for a solution if all metric values have a value so that a
|
||||||
// the constructor.
|
// proper metric context can be forwarded to the solver.
|
||||||
|
|
||||||
bool AllMetricValuesSet;
|
unsigned int UnsetMetrics;
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
// Subscribing to metric prediction values
|
// Subscribing to metric prediction values
|
||||||
@ -363,6 +363,54 @@ private:
|
|||||||
|
|
||||||
const Address TheSolverManager;
|
const Address TheSolverManager;
|
||||||
|
|
||||||
|
// After the sending of the application's excution context, one should not
|
||||||
|
// initiate another reconfiguration because the state may the possibly be
|
||||||
|
// inconsistent with the SLO Violation Detector belieivng that the old
|
||||||
|
// configuration is still in effect while the new configuration is being
|
||||||
|
// enacted. It is therefore a flag that will be set by the SLO Violation
|
||||||
|
// handler indicating that a reconfiguration is ongoing.
|
||||||
|
|
||||||
|
bool ReconfigurationInProgress;
|
||||||
|
|
||||||
|
// When a reconfiguration has been enacted by the Optimiser Controller and
|
||||||
|
// a new configuration is confirmed to be running on the new platofrm, it
|
||||||
|
// will send a message to inform all other components that the
|
||||||
|
// reconfiguration has happened. The event is just the reception of the
|
||||||
|
// message and its content will not be processed, so there are no keys for
|
||||||
|
// the JSON map received.
|
||||||
|
|
||||||
|
class ReconfigurationMessage
|
||||||
|
: public Theron::AMQ::JSONTopicMessage
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
// The topic for the reconfiguration finished messages is defined by the
|
||||||
|
// optimiser as the sender.
|
||||||
|
|
||||||
|
static constexpr std::string_view AMQTopic
|
||||||
|
= "eu.nebulouscloud.optimiser.controller.reconfiguration";
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
ReconfigurationMessage( void )
|
||||||
|
: JSONTopicMessage( AMQTopic )
|
||||||
|
{}
|
||||||
|
|
||||||
|
ReconfigurationMessage( const ReconfigurationMessage & Other )
|
||||||
|
: JSONTopicMessage( Other )
|
||||||
|
{}
|
||||||
|
|
||||||
|
virtual ~ReconfigurationMessage() = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
// The handler for this message will actually not use its contents, but only
|
||||||
|
// note that the reconfiguration has been completed to reset the
|
||||||
|
// reconfiguration in progress flag allowing future SLO Violation Events to
|
||||||
|
// triger new reconfigurations.
|
||||||
|
|
||||||
|
void ReconfigurationDone( const ReconfigurationMessage & TheReconfiguraton,
|
||||||
|
const Address TheReconfigurationTopic );
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
// Constructor and destructor
|
// Constructor and destructor
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
|
Loading…
x
Reference in New Issue
Block a user