Skip to content
This repository has been archived by the owner on Jan 7, 2022. It is now read-only.

Commit

Permalink
MaintenanceManager: Implement helpers to remove non existent nodes fr…
Browse files Browse the repository at this point in the history
…om maintenance and to check if a maintenance is empty

Summary:
Two new helper functions to:
1- Given a maintenance, remove all the non existent shards/sequencers out of it.
2- Given a maintenance, checks whether the maintenance is empty or not (usually used after #1).

Reviewed By: AhmedSoliman

Differential Revision: D17684399

fbshipit-source-id: 27eb1324eddb4f214f2ac86303edd1367682cac2
  • Loading branch information
MohamedBassem authored and facebook-github-bot committed Oct 1, 2019
1 parent f439580 commit 3b7e376
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 0 deletions.
27 changes: 27 additions & 0 deletions logdevice/admin/maintenance/APIUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -370,5 +370,32 @@ bool doesMaintenanceMatchFilter(const thrift::MaintenancesFilter& filter,
return true;
}

void removeNonExistentNodesFromMaintenance(
thrift::MaintenanceDefinition& maintenance,
const configuration::nodes::NodesConfiguration& nodes_configuration) {
maintenance.shards.erase(
std::remove_if(maintenance.shards.begin(),
maintenance.shards.end(),
[&](const auto& shard) {
return !findNodeIndex(
shard.get_node(), nodes_configuration)
.hasValue();
}),
maintenance.shards.end());
maintenance.sequencer_nodes.erase(
std::remove_if(
maintenance.sequencer_nodes.begin(),
maintenance.sequencer_nodes.end(),
[&](const auto& node) {
return !findNodeIndex(node, nodes_configuration).hasValue();
}),
maintenance.sequencer_nodes.end());
}

bool isEmptyMaintenance(const thrift::MaintenanceDefinition& maintenance) {
return maintenance.get_shards().empty() &&
maintenance.get_sequencer_nodes().empty();
}

} // namespace APIUtils
}}} // namespace facebook::logdevice::maintenance
13 changes: 13 additions & 0 deletions logdevice/admin/maintenance/APIUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,5 +118,18 @@ void matchMaintenances(const thrift::MaintenancesFilter& filter,
bool doesMaintenanceMatchFilter(const thrift::MaintenancesFilter& filter,
const MaintenanceDefinition& def);

/**
* Filters out shards/sequencers from maintenance definition that don't exist in
* the nodes configuration anymore.
*/
void removeNonExistentNodesFromMaintenance(
thrift::MaintenanceDefinition& maintenance,
const configuration::nodes::NodesConfiguration& nodes_configuration);

/**
* Returns true if the maintenance doesn't have any shards/sequencers to act on.
*/
bool isEmptyMaintenance(const thrift::MaintenanceDefinition& maintenance);

} // namespace APIUtils
}}} // namespace facebook::logdevice::maintenance
50 changes: 50 additions & 0 deletions logdevice/admin/maintenance/test/APIUtilsTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -389,3 +389,53 @@ TEST(APIUtilsTest, MaintenanceFilter) {
ASSERT_EQ(1, res1.size());
ASSERT_THAT(res1, UnorderedElementsAre(def1));
}

TEST(APIUtilsTest, TestIsEmptyMaintenance) {
MaintenanceDefinition def;
def.set_user("bunny");
def.set_shard_target_state(ShardOperationalState::DRAINED);
def.set_shards({mkShardID(1, -1), mkShardID(13, -1)});
def.set_sequencer_nodes({mkNodeID(1)});
def.set_sequencer_target_state(SequencingState::DISABLED);
EXPECT_FALSE(APIUtils::isEmptyMaintenance(def));

def.set_shards({});
def.set_sequencer_nodes({mkNodeID(1)});
EXPECT_FALSE(APIUtils::isEmptyMaintenance(def));

def.set_shards({mkShardID(1, -1), mkShardID(13, -1)});
def.set_sequencer_nodes({});
EXPECT_FALSE(APIUtils::isEmptyMaintenance(def));

def.set_shards({});
def.set_sequencer_nodes({});
EXPECT_TRUE(APIUtils::isEmptyMaintenance(def));
}

TEST(APIUtilsTest, TestRemoveNonExistentNodesFromMaintenance) {
MaintenanceDefinition def;
def.set_user("bunny");
def.set_shard_target_state(ShardOperationalState::DRAINED);
def.set_shards(
{mkShardID(1, -1), mkShardID(130, 0), mkShardID(0, 1), mkShardID(7, 1)});
def.set_sequencer_nodes(
{mkNodeID(1), mkNodeID(100), mkNodeID(0), mkNodeID(101)});
def.set_sequencer_target_state(SequencingState::DISABLED);

APIUtils::removeNonExistentNodesFromMaintenance(
def, *genNodesConfiguration());

for (auto seq : def.get_sequencer_nodes()) {
LOG(INFO) << *seq.get_node_index();
}

EXPECT_THAT(def.get_shards(),
UnorderedElementsAre(mkShardID(1, -1), mkShardID(7, 1)));
EXPECT_THAT(def.get_sequencer_nodes(), UnorderedElementsAre(mkNodeID(1)));

// Trying to remove the nodes again, wouldn't change anything
auto def_copy = def;
APIUtils::removeNonExistentNodesFromMaintenance(
def_copy, *genNodesConfiguration());
EXPECT_EQ(def, def_copy);
}

0 comments on commit 3b7e376

Please sign in to comment.