2
0
mirror of https://gitlab.isc.org/isc-projects/kea synced 2025-08-31 14:05:33 +00:00

[#1024] Implemented state handlers

There are now new handlers for the maintained and partner-maintained state.
This commit is contained in:
Marcin Siodelski
2020-01-14 11:20:33 +01:00
parent 3f5acda310
commit 22d64dbce6
2 changed files with 98 additions and 15 deletions

View File

@@ -203,6 +203,24 @@ HAService::normalStateHandler() {
void
HAService::maintainedStateHandler() {
// If we are transitioning from another state, we have to define new
// serving scopes appropriate for the new state. We don't do it if
// we remain in this state.
if (doOnEntry()) {
// In this state the server remains silent and waits for being
// shutdown.
query_filter_.serveNoScopes();
adjustNetworkState();
// Log if the state machine is paused.
conditionalLogPausedState();
}
scheduleHeartbeat();
// We don't transition out of this state unless explicitly mandated
// by the administrator via a dedicated command which cancels
// the maintenance.
postNextEvent(NOP_EVT);
}
@@ -265,7 +283,46 @@ HAService::partnerDownStateHandler() {
void
HAService::partnerMaintainedStateHandler() {
postNextEvent(NOP_EVT);
// If we are transitioning from another state, we have to define new
// serving scopes appropriate for the new state. We don't do it if
// we remain in this state.
if (doOnEntry()) {
// It may be administratively disabled to handle partner's scope
// in case of failure. If this is the case we'll just handle our
// default scope (or no scope at all). The user will need to
// manually enable this server to handle partner's scope.
if (config_->getThisServerConfig()->isAutoFailover()) {
query_filter_.serveFailoverScopes();
} else {
query_filter_.serveDefaultScopes();
}
adjustNetworkState();
// Log if the state machine is paused.
conditionalLogPausedState();
}
scheduleHeartbeat();
if (isModelPaused()) {
postNextEvent(NOP_EVT);
return;
}
// Check if the clock skew is still acceptable. If not, transition to
// the terminated state.
if (shouldTerminate()) {
verboseTransition(HA_TERMINATED_ST);
return;
}
switch (communication_state_->getPartnerState()) {
case HA_UNAVAILABLE_ST:
verboseTransition(HA_PARTNER_DOWN_ST);
default:
postNextEvent(NOP_EVT);
}
}
void
@@ -645,6 +702,7 @@ HAService::adjustNetworkState() {
const bool should_enable = ((getCurrState() == HA_LOAD_BALANCING_ST) ||
(getCurrState() == HA_HOT_STANDBY_ST) ||
(getCurrState() == HA_PARTNER_DOWN_ST) ||
(getCurrState() == HA_PARTNER_MAINTAINED_ST) ||
(getCurrState() == HA_TERMINATED_ST));
if (!should_enable && network_state_->isServiceEnabled()) {
@@ -928,6 +986,7 @@ HAService::shouldSendLeaseUpdates(const HAConfig::PeerConfigPtr& peer_config) co
switch (getCurrState()) {
case HA_HOT_STANDBY_ST:
case HA_LOAD_BALANCING_ST:
case HA_PARTNER_MAINTAINED_ST:
return (true);
default:

View File

@@ -4045,10 +4045,12 @@ TEST_F(HAServiceStateMachineTest, scopesServingLoadBalancing) {
expectScopes(MyState(HA_LOAD_BALANCING_ST), { "server1" }, true);
expectScopes(MyState(HA_TERMINATED_ST), { "server1" }, true);
// PARTNER DOWN: serving both scopes.
// PARTNER DOWN and PARTNER MAINTAINED: serving both scopes.
expectScopes(MyState(HA_PARTNER_DOWN_ST), { "server1", "server2" }, true);
expectScopes(MyState(HA_PARTNER_MAINTAINED_ST), { "server1", "server2" }, true);
// READY & WAITING: serving no scopes.
// MAINTAINED, READY & WAITING: serving no scopes.
expectScopes(MyState(HA_MAINTAINED_ST), { }, false);
expectScopes(MyState(HA_READY_ST), { }, false);
expectScopes(MyState(HA_WAITING_ST), { }, false);
}
@@ -4064,11 +4066,13 @@ TEST_F(HAServiceStateMachineTest, scopesServingLoadBalancingNoFailover) {
expectScopes(MyState(HA_LOAD_BALANCING_ST), { "server1" }, true);
expectScopes(MyState(HA_TERMINATED_ST), { "server1" }, true);
// PARTNER DOWN: still serving my own scope because auto-failover
// is disabled.
// PARTNER MAINTAINED & PARTNER DOWN: still serving my own scope
// because auto-failover is disabled.
expectScopes(MyState(HA_PARTNER_DOWN_ST), { "server1" }, true);
expectScopes(MyState(HA_PARTNER_MAINTAINED_ST), { "server1" }, true);
// READY & WAITING: serving no scopes.
// MAINTAINED, READY & WAITING: serving no scopes.
expectScopes(MyState(HA_MAINTAINED_ST), { }, false);
expectScopes(MyState(HA_READY_ST), { }, false);
expectScopes(MyState(HA_WAITING_ST), { }, false);
}
@@ -4082,7 +4086,9 @@ TEST_F(HAServiceStateMachineTest, shouldSendLeaseUpdatesLoadBalancing) {
HAConfig::PeerConfigPtr peer_config = valid_config->getFailoverPeerConfig();
EXPECT_TRUE(expectLeaseUpdates(MyState(HA_LOAD_BALANCING_ST), peer_config));
EXPECT_FALSE(expectLeaseUpdates(MyState(HA_MAINTAINED_ST), peer_config));
EXPECT_FALSE(expectLeaseUpdates(MyState(HA_PARTNER_DOWN_ST), peer_config));
EXPECT_TRUE(expectLeaseUpdates(MyState(HA_PARTNER_MAINTAINED_ST), peer_config));
EXPECT_FALSE(expectLeaseUpdates(MyState(HA_READY_ST), peer_config));
EXPECT_FALSE(expectLeaseUpdates(MyState(HA_SYNCING_ST), peer_config));
EXPECT_FALSE(expectLeaseUpdates(MyState(HA_TERMINATED_ST), peer_config));
@@ -4100,7 +4106,9 @@ TEST_F(HAServiceStateMachineTest, shouldSendLeaseUpdatesDisabledLoadBalancing) {
HAConfig::PeerConfigPtr peer_config = valid_config->getFailoverPeerConfig();
EXPECT_FALSE(expectLeaseUpdates(MyState(HA_LOAD_BALANCING_ST), peer_config));
EXPECT_FALSE(expectLeaseUpdates(MyState(HA_MAINTAINED_ST), peer_config));
EXPECT_FALSE(expectLeaseUpdates(MyState(HA_PARTNER_DOWN_ST), peer_config));
EXPECT_FALSE(expectLeaseUpdates(MyState(HA_PARTNER_MAINTAINED_ST), peer_config));
EXPECT_FALSE(expectLeaseUpdates(MyState(HA_READY_ST), peer_config));
EXPECT_FALSE(expectLeaseUpdates(MyState(HA_SYNCING_ST), peer_config));
EXPECT_FALSE(expectLeaseUpdates(MyState(HA_TERMINATED_ST), peer_config));
@@ -4114,7 +4122,9 @@ TEST_F(HAServiceStateMachineTest, heartbeatLoadBalancing) {
startService(valid_config);
EXPECT_TRUE(expectHeartbeat(MyState(HA_LOAD_BALANCING_ST)));
EXPECT_TRUE(expectHeartbeat(MyState(HA_MAINTAINED_ST)));
EXPECT_TRUE(expectHeartbeat(MyState(HA_PARTNER_DOWN_ST)));
EXPECT_TRUE(expectHeartbeat(MyState(HA_PARTNER_MAINTAINED_ST)));
EXPECT_TRUE(expectHeartbeat(MyState(HA_READY_ST)));
EXPECT_FALSE(expectHeartbeat(MyState(HA_TERMINATED_ST)));
EXPECT_TRUE(expectHeartbeat(MyState(HA_WAITING_ST)));
@@ -4519,10 +4529,12 @@ TEST_F(HAServiceStateMachineTest, scopesServingHotStandbyPrimary) {
expectScopes(MyState(HA_HOT_STANDBY_ST), { "server1" }, true);
expectScopes(MyState(HA_TERMINATED_ST), { "server1" }, true);
// PARTNER DOWN: still serving my own scope.
// PARTNER DOWN and PARTNER MAINTAINED: still serving my own scope.
expectScopes(MyState(HA_PARTNER_DOWN_ST), { "server1" }, true);
expectScopes(MyState(HA_PARTNER_MAINTAINED_ST), { "server1" }, true);
// READY & WAITING: serving no scopes.
// MAINTAINED, READY & WAITING: serving no scopes.
expectScopes(MyState(HA_MAINTAINED_ST), { }, false);
expectScopes(MyState(HA_READY_ST), { }, false);
expectScopes(MyState(HA_WAITING_ST), { }, false);
}
@@ -4544,10 +4556,12 @@ TEST_F(HAServiceStateMachineTest, scopesServingHotStandbyPrimaryNoFailover) {
expectScopes(MyState(HA_HOT_STANDBY_ST), { "server1" }, true);
expectScopes(MyState(HA_TERMINATED_ST), { "server1" }, true);
// PARTNER DOWN: still serving my own scope.
// PARTNER MAINTAINED & PARTNER DOWN: still serving my own scope.
expectScopes(MyState(HA_PARTNER_DOWN_ST), { "server1" }, true);
expectScopes(MyState(HA_PARTNER_MAINTAINED_ST), { "server1" }, true);
// READY & WAITING: serving no scopes.
// MAINTAINED, READY & WAITING: serving no scopes.
expectScopes(MyState(HA_MAINTAINED_ST), { }, false);
expectScopes(MyState(HA_READY_ST), { }, false);
expectScopes(MyState(HA_WAITING_ST), { }, false);
}
@@ -4567,7 +4581,9 @@ TEST_F(HAServiceStateMachineTest, shouldSendLeaseUpdatesHotStandbyPrimary) {
HAConfig::PeerConfigPtr peer_config = valid_config->getFailoverPeerConfig();
EXPECT_TRUE(expectLeaseUpdates(MyState(HA_HOT_STANDBY_ST), peer_config));
EXPECT_FALSE(expectLeaseUpdates(MyState(HA_MAINTAINED_ST), peer_config));
EXPECT_FALSE(expectLeaseUpdates(MyState(HA_PARTNER_DOWN_ST), peer_config));
EXPECT_TRUE(expectLeaseUpdates(MyState(HA_PARTNER_MAINTAINED_ST), peer_config));
EXPECT_FALSE(expectLeaseUpdates(MyState(HA_READY_ST), peer_config));
EXPECT_FALSE(expectLeaseUpdates(MyState(HA_SYNCING_ST), peer_config));
EXPECT_FALSE(expectLeaseUpdates(MyState(HA_TERMINATED_ST), peer_config));
@@ -4576,7 +4592,7 @@ TEST_F(HAServiceStateMachineTest, shouldSendLeaseUpdatesHotStandbyPrimary) {
// This test verifies if the server would send heartbeat to the partner
// while being in various states. The HA configuration is hot standby.
TEST_F(HAServiceStateMachineTest, heartbeatHotstandby) {
TEST_F(HAServiceStateMachineTest, heartbeatHotStandby) {
HAConfigPtr valid_config = createValidConfiguration();
// Turn it into hot-standby configuration.
@@ -4586,7 +4602,9 @@ TEST_F(HAServiceStateMachineTest, heartbeatHotstandby) {
startService(valid_config);
EXPECT_TRUE(expectHeartbeat(MyState(HA_HOT_STANDBY_ST)));
EXPECT_TRUE(expectHeartbeat(MyState(HA_MAINTAINED_ST)));
EXPECT_TRUE(expectHeartbeat(MyState(HA_PARTNER_DOWN_ST)));
EXPECT_TRUE(expectHeartbeat(MyState(HA_PARTNER_MAINTAINED_ST)));
EXPECT_TRUE(expectHeartbeat(MyState(HA_READY_ST)));
EXPECT_FALSE(expectHeartbeat(MyState(HA_TERMINATED_ST)));
EXPECT_TRUE(expectHeartbeat(MyState(HA_WAITING_ST)));
@@ -4613,10 +4631,12 @@ TEST_F(HAServiceStateMachineTest, scopesServingHotStandbyStandby) {
// TERMINATED: serving no scopes because the primary is active.
expectScopes(MyState(HA_TERMINATED_ST), { }, true);
// PARTNER DOWN: serving server1's scope.
// PARTNER MAINTAINED & PARTNER DOWN: serving server1's scope.
expectScopes(MyState(HA_PARTNER_DOWN_ST), { "server1" }, true);
expectScopes(MyState(HA_PARTNER_MAINTAINED_ST), { "server1" }, true);
// READY & WAITING: serving no scopes.
// MAINTAINED, READY & WAITING: serving no scopes.
expectScopes(MyState(HA_MAINTAINED_ST), { }, false);
expectScopes(MyState(HA_READY_ST), { }, false);
expectScopes(MyState(HA_WAITING_ST), { }, false);
}
@@ -4644,11 +4664,13 @@ TEST_F(HAServiceStateMachineTest, scopesServingHotStandbyStandbyNoFailover) {
// TERMINATED: serving no scopes because the primary is active.
expectScopes(MyState(HA_TERMINATED_ST), { }, true);
// PARTNER DOWN: still serving no scopes because auto-failover is
// PARTNER MAINTAINED & PARTNER DOWN: still serving no scopes because auto-failover is
// set to false.
expectScopes(MyState(HA_PARTNER_DOWN_ST), { }, true);
expectScopes(MyState(HA_PARTNER_MAINTAINED_ST), { }, true);
// READY & WAITING: serving no scopes.
// MAINTAINED, READY & WAITING: serving no scopes.
expectScopes(MyState(HA_MAINTAINED_ST), { }, false);
expectScopes(MyState(HA_READY_ST), { }, false);
expectScopes(MyState(HA_WAITING_ST), { }, false);
}
@@ -4669,7 +4691,9 @@ TEST_F(HAServiceStateMachineTest, shouldSendLeaseUpdatesHotStandbyStandby) {
HAConfig::PeerConfigPtr peer_config = valid_config->getFailoverPeerConfig();
EXPECT_TRUE(expectLeaseUpdates(MyState(HA_HOT_STANDBY_ST), peer_config));
EXPECT_FALSE(expectLeaseUpdates(MyState(HA_MAINTAINED_ST), peer_config));
EXPECT_FALSE(expectLeaseUpdates(MyState(HA_PARTNER_DOWN_ST), peer_config));
EXPECT_TRUE(expectLeaseUpdates(MyState(HA_PARTNER_MAINTAINED_ST), peer_config));
EXPECT_FALSE(expectLeaseUpdates(MyState(HA_READY_ST), peer_config));
EXPECT_FALSE(expectLeaseUpdates(MyState(HA_SYNCING_ST), peer_config));
EXPECT_FALSE(expectLeaseUpdates(MyState(HA_TERMINATED_ST), peer_config));