Support for application lifecycle message
Change-Id: I16db05bccb9ac9a2d18b949952e5ad6812b729cc
This commit is contained in:
parent
58b37118fb
commit
58ec992fe3
@ -147,6 +147,42 @@ void MetricUpdater::UpdateMetricValue(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// Application lifcycle
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// When the lifecycle message is received, the state is just recorded in the
|
||||||
|
// state variable.
|
||||||
|
|
||||||
|
void MetricUpdater::LifecycleHandler(
|
||||||
|
const ApplicationLifecycle & TheState,
|
||||||
|
const Address TheLifecycleTopic )
|
||||||
|
{
|
||||||
|
Theron::ConsoleOutput Output;
|
||||||
|
|
||||||
|
ApplicationState = TheState;
|
||||||
|
|
||||||
|
Output << "Application state updated: " << std::endl
|
||||||
|
<< TheState.dump(2) << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The message handler used the conversion operator to read out the state
|
||||||
|
// carried in the message. It is based on having a static map from the textual
|
||||||
|
// representation of the state to the enumeration.
|
||||||
|
|
||||||
|
MetricUpdater::ApplicationLifecycle::operator State() const
|
||||||
|
{
|
||||||
|
static std::map< std::string_view, State > LifecycleStates{
|
||||||
|
{"NEW", State::New},
|
||||||
|
{"READY", State::Ready},
|
||||||
|
{"DEPLOYING", State::Deploying},
|
||||||
|
{"RUNNING", State::Running},
|
||||||
|
{"FAILED", State::Failed}
|
||||||
|
};
|
||||||
|
|
||||||
|
return LifecycleStates.at( this->at("state").get< std::string >() );
|
||||||
|
}
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
// SLO Violation Events
|
// SLO Violation Events
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
@ -174,7 +210,7 @@ void MetricUpdater::SLOViolationHandler(
|
|||||||
Output << "Metric Updater: SLO violation received " << std::endl
|
Output << "Metric Updater: SLO violation received " << std::endl
|
||||||
<< SeverityMessage.dump(2) << std::endl;
|
<< SeverityMessage.dump(2) << std::endl;
|
||||||
|
|
||||||
if( !ReconfigurationInProgress &&
|
if(( ApplicationState == ApplicationLifecycle::State::Running ) &&
|
||||||
( AllMetricValuesSet ||
|
( AllMetricValuesSet ||
|
||||||
(!MetricValues.empty() &&
|
(!MetricValues.empty() &&
|
||||||
std::ranges::none_of( std::views::values( MetricValues ),
|
std::ranges::none_of( std::views::values( MetricValues ),
|
||||||
@ -187,37 +223,13 @@ void MetricUpdater::SLOViolationHandler(
|
|||||||
), TheSolverManager );
|
), TheSolverManager );
|
||||||
|
|
||||||
AllMetricValuesSet = true;
|
AllMetricValuesSet = true;
|
||||||
ReconfigurationInProgress = true;
|
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() << ")" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
// Reconfigured application
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// When the reconfiguration message is received it is an indication tha the
|
|
||||||
// Optimiser Controller has reconfigured the application and that the
|
|
||||||
// application is running in the new configuration found by the solver.
|
|
||||||
// It is the event that is important m not the content of the message, and
|
|
||||||
// it is therefore only used to reset the ongoing reconfiguration flag.
|
|
||||||
|
|
||||||
void MetricUpdater::ReconfigurationDone(
|
|
||||||
const ReconfigurationMessage & TheReconfiguraton,
|
|
||||||
const Address TheReconfigurationTopic )
|
|
||||||
{
|
|
||||||
Theron::ConsoleOutput Output;
|
|
||||||
|
|
||||||
ReconfigurationInProgress = false;
|
|
||||||
|
|
||||||
Output << "Reconfiguration ongoing flag reset after receiving the following "
|
|
||||||
<< "message indicating that the previous reconfiguration was"
|
|
||||||
<< "completed: " << std::endl
|
|
||||||
<< TheReconfiguraton.dump(2) << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
// Constructor and destructor
|
// Constructor and destructor
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
@ -239,13 +251,13 @@ MetricUpdater::MetricUpdater( const std::string 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), AllMetricValuesSet(false),
|
||||||
TheSolverManager( ManagerOfSolvers ),
|
ApplicationState( ApplicationLifecycle::State::New ),
|
||||||
ReconfigurationInProgress( false )
|
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::SLOViolationHandler );
|
||||||
RegisterHandler( this, &MetricUpdater::ReconfigurationDone );
|
RegisterHandler( this, &MetricUpdater::LifecycleHandler );
|
||||||
|
|
||||||
Send( Theron::AMQ::NetworkLayer::TopicSubscription(
|
Send( Theron::AMQ::NetworkLayer::TopicSubscription(
|
||||||
Theron::AMQ::NetworkLayer::TopicSubscription::Action::Subscription,
|
Theron::AMQ::NetworkLayer::TopicSubscription::Action::Subscription,
|
||||||
@ -254,7 +266,7 @@ MetricUpdater::MetricUpdater( const std::string UpdaterName,
|
|||||||
|
|
||||||
Send( Theron::AMQ::NetworkLayer::TopicSubscription(
|
Send( Theron::AMQ::NetworkLayer::TopicSubscription(
|
||||||
Theron::AMQ::NetworkLayer::TopicSubscription::Action::Subscription,
|
Theron::AMQ::NetworkLayer::TopicSubscription::Action::Subscription,
|
||||||
ReconfigurationMessage::AMQTopic ),
|
ApplicationLifecycle::AMQTopic ),
|
||||||
GetSessionLayerAddress() );
|
GetSessionLayerAddress() );
|
||||||
|
|
||||||
Send( Theron::AMQ::NetworkLayer::TopicSubscription(
|
Send( Theron::AMQ::NetworkLayer::TopicSubscription(
|
||||||
@ -279,7 +291,7 @@ MetricUpdater::~MetricUpdater()
|
|||||||
|
|
||||||
Send( Theron::AMQ::NetworkLayer::TopicSubscription(
|
Send( Theron::AMQ::NetworkLayer::TopicSubscription(
|
||||||
Theron::AMQ::NetworkLayer::TopicSubscription::Action::CloseSubscription,
|
Theron::AMQ::NetworkLayer::TopicSubscription::Action::CloseSubscription,
|
||||||
ReconfigurationMessage::AMQTopic ),
|
ApplicationLifecycle::AMQTopic ),
|
||||||
GetSessionLayerAddress() );
|
GetSessionLayerAddress() );
|
||||||
|
|
||||||
Send( Theron::AMQ::NetworkLayer::TopicSubscription(
|
Send( Theron::AMQ::NetworkLayer::TopicSubscription(
|
||||||
|
@ -225,6 +225,74 @@ private:
|
|||||||
void UpdateMetricValue( const MetricValueUpdate & TheMetricValue,
|
void UpdateMetricValue( const MetricValueUpdate & TheMetricValue,
|
||||||
const Address TheMetricTopic );
|
const Address TheMetricTopic );
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// Application lifecycle
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// There is a message from the Optimiser Controller when the status of the
|
||||||
|
// application changes. The state communicated in this message shows the
|
||||||
|
// current state of the application and decides how the Solver will act to
|
||||||
|
// SLO Violations detected.
|
||||||
|
|
||||||
|
class ApplicationLifecycle
|
||||||
|
: 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.app_state";
|
||||||
|
|
||||||
|
// The state of the application goes from the the initial creation of
|
||||||
|
// the cluster to deployments covering reconfigurations. Note that there is
|
||||||
|
// no state indicating that the application has terminated.
|
||||||
|
|
||||||
|
enum class State
|
||||||
|
{
|
||||||
|
New, // Waiting for the utility evaluator
|
||||||
|
Ready, // The application is ready for deployment
|
||||||
|
Deploying, // The application is being deployed or redeployed
|
||||||
|
Running, // The application is running
|
||||||
|
Failed // The application is in an invalid state
|
||||||
|
};
|
||||||
|
|
||||||
|
// An arriving lifecycle message indicates a change in state and it is
|
||||||
|
// therefore a way to set a state variable directly from the message by
|
||||||
|
// a cast operator
|
||||||
|
|
||||||
|
operator State() const;
|
||||||
|
|
||||||
|
// Constructors and destructor
|
||||||
|
|
||||||
|
ApplicationLifecycle( void )
|
||||||
|
: JSONTopicMessage( AMQTopic )
|
||||||
|
{}
|
||||||
|
|
||||||
|
ApplicationLifecycle( const ApplicationLifecycle & Other )
|
||||||
|
: JSONTopicMessage( Other )
|
||||||
|
{}
|
||||||
|
|
||||||
|
virtual ~ApplicationLifecycle() = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
// After starting a reconfiguration with an SLO Violation, 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. The application lifecycle state must therefore be marked as
|
||||||
|
// running before the another SLO Violation will trigger the next
|
||||||
|
// reconfiguration
|
||||||
|
|
||||||
|
ApplicationLifecycle::State ApplicationState;
|
||||||
|
|
||||||
|
// The handler for the lifecycle message simply updates this variable by
|
||||||
|
// setting it to the state received in the lifecycle message.
|
||||||
|
|
||||||
|
void LifecycleHandler( const ApplicationLifecycle & TheState,
|
||||||
|
const Address TheLifecycleTopic );
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
// SLO violations
|
// SLO violations
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
@ -295,54 +363,6 @@ 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…
Reference in New Issue
Block a user