Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 34 additions & 21 deletions src/core/cm/launcher/balancer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,14 @@
LOG_DBG() << "Try to schedule instance" << Log::Field("instance", id)
<< Log::Field("manifest", manifest.mDigest);

scheduleErr = ScheduleInstance(instance, manifest);
Pair<Node*, const RuntimeInfo*> nodeRuntime {nullptr, nullptr};

auto scheduleResult = TryScheduleInstance(instance, manifest, nodeRuntime);
if (scheduleResult.mResult == ScheduleDecision::eSkipManifest) {
continue;
}

scheduleErr = scheduleResult.mError;
if (scheduleErr.IsNone()) {
LOG_DBG() << "Instance scheduled successfully" << Log::Field("nodeID", info.mNodeID);

Expand All @@ -124,39 +131,40 @@
return ErrorEnum::eNone;
}

Error Balancer::ScheduleInstance(SharedPtr<Instance>& instance, const oci::IndexContentDescriptor& imageDescriptor)
Balancer::ScheduleResult Balancer::TryScheduleInstance(SharedPtr<Instance>& instance,
const oci::IndexContentDescriptor& imageDescriptor, Pair<Node*, const RuntimeInfo*>& nodeRuntime)
{
auto nodes = MakeUnique<StaticArray<Node*, cMaxNumNodes>>(&mAllocator);

auto releaseConfigs = DeferRelease(reinterpret_cast<int*>(1), [&](int*) { instance->ResetConfigs(); });

if (auto err = instance->LoadConfigs(imageDescriptor); !err.IsNone()) {
return AOS_ERROR_WRAP(Error(err, "can't load instance configs"));
return {ScheduleDecision::eError, AOS_ERROR_WRAP(Error(err, "can't load instance configs"))};
}

// Select node runtimes
if (auto err = mNodeManager->GetConnectedNodes(*nodes); !err.IsNone()) {
return AOS_ERROR_WRAP(Error(err, "get connected nodes failed"));
return {ScheduleDecision::eError, AOS_ERROR_WRAP(Error(err, "get connected nodes failed"))};
}

if (auto err = SelectNodes(*instance, *nodes); !err.IsNone()) {
return AOS_ERROR_WRAP(Error(err, "can't find node for instance"));
return {ScheduleDecision::eSkipManifest, ErrorEnum::eNone};
}

auto [nodeRuntime, selectErr] = SelectRuntime(*instance, *nodes);
if (!selectErr.IsNone()) {
return AOS_ERROR_WRAP(Error(selectErr, "can't find runtime for instance"));
auto selectRuntimeResult = SelectRuntime(*instance, *nodes, nodeRuntime);
if (selectRuntimeResult.mResult != ScheduleDecision::eScheduled) {

Check warning on line 155 in src/core/cm/launcher/balancer.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use the init-statement to declare "selectRuntimeResult" inside the if statement.

See more on https://sonarcloud.io/project/issues?id=aosedge_aos_core_lib_cpp&issues=AZ5PFWisLY4tfplsDiOx&open=AZ5PFWisLY4tfplsDiOx&pullRequest=572
return selectRuntimeResult;
}

// Schedule instance
// Schedule instance.
auto& node = nodeRuntime.mFirst;
const auto& runtime = nodeRuntime.mSecond;

if (auto err = mInstanceManager->ScheduleInstance(instance, *node, runtime->mRuntimeID); !err.IsNone()) {
return AOS_ERROR_WRAP(Error(err, "can't schedule instance"));
return {ScheduleDecision::eError, AOS_ERROR_WRAP(Error(err, "can't schedule instance"))};
}

return ErrorEnum::eNone;
return {ScheduleDecision::eScheduled, ErrorEnum::eNone};
}

Error Balancer::SelectNodes(Instance& instance, Array<Node*>& nodes)
Expand Down Expand Up @@ -194,42 +202,47 @@
nodes.RemoveIf([&instance](const Node* node) { return !instance.AreNodeResourcesOk(node->GetInfo().mResources); });
}

RetWithError<Pair<Node*, const RuntimeInfo*>> Balancer::SelectRuntime(Instance& instance, Array<Node*>& nodes)
Balancer::ScheduleResult Balancer::SelectRuntime(
Instance& instance, Array<Node*>& nodes, Pair<Node*, const RuntimeInfo*>& nodeRuntime)
{
auto nodeRuntimes = MakeUnique<NodeRuntimes>(&mAllocator);

if (auto err = CreateRuntimes(nodes, *nodeRuntimes); !err.IsNone()) {
return {nullptr, AOS_ERROR_WRAP(err)};
return {ScheduleDecision::eError, AOS_ERROR_WRAP(err)};
}

FilterByRuntimeType(instance, *nodeRuntimes);
if (nodeRuntimes->IsEmpty()) {
return {nullptr, AOS_ERROR_WRAP(Error(ErrorEnum::eNotFound, "no runtimes with requested runtime type"))};
return {ScheduleDecision::eSkipManifest, ErrorEnum::eNone};
}

FilterByPlatform(instance, *nodeRuntimes);
if (nodeRuntimes->IsEmpty()) {
return {nullptr, AOS_ERROR_WRAP(Error(ErrorEnum::eNotFound, "no runtimes with requested platform"))};
return {ScheduleDecision::eSkipManifest, ErrorEnum::eNone};
}

FilterByCPU(instance, *nodeRuntimes);
if (nodeRuntimes->IsEmpty()) {
return {nullptr, AOS_ERROR_WRAP(Error(ErrorEnum::eNotFound, "no runtimes with requested CPU"))};
return {
ScheduleDecision::eError, AOS_ERROR_WRAP(Error(ErrorEnum::eNotFound, "no runtimes with requested CPU"))};
}

FilterByRAM(instance, *nodeRuntimes);
if (nodeRuntimes->IsEmpty()) {
return {nullptr, AOS_ERROR_WRAP(Error(ErrorEnum::eNotFound, "no runtimes with requested RAM"))};
return {
ScheduleDecision::eError, AOS_ERROR_WRAP(Error(ErrorEnum::eNotFound, "no runtimes with requested RAM"))};
}

FilterByNumInstances(*nodeRuntimes);
if (nodeRuntimes->IsEmpty()) {
return {nullptr, AOS_ERROR_WRAP(Error(ErrorEnum::eNotFound, "no runtimes with requested RAM"))};
return {
ScheduleDecision::eError, AOS_ERROR_WRAP(Error(ErrorEnum::eNotFound, "no runtimes with requested RAM"))};
}

FilterTopPriorityNodes(*nodeRuntimes);
if (nodeRuntimes->IsEmpty()) {
return {nullptr, AOS_ERROR_WRAP(Error(ErrorEnum::eNotFound, "failed top priority nodes filtering"))};
return {ScheduleDecision::eError,
AOS_ERROR_WRAP(Error(ErrorEnum::eNotFound, "failed top priority nodes filtering"))};
}

// Select best node.
Expand Down Expand Up @@ -260,9 +273,9 @@
[](const RuntimeInfo* left, const RuntimeInfo* right) { return left->mRuntimeType < right->mRuntimeType; });

// Return result.
Pair<Node*, const RuntimeInfo*> result {bestNode.mFirst, bestNodeRuntimes.Front()};
nodeRuntime = {bestNode.mFirst, bestNodeRuntimes.Front()};

return {result, ErrorEnum::eNone};
return {ScheduleDecision::eScheduled, ErrorEnum::eNone};
}

Error Balancer::CreateRuntimes(Array<Node*>& nodes, NodeRuntimes& runtimes)
Expand Down
11 changes: 9 additions & 2 deletions src/core/cm/launcher/balancer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,12 @@

private:
using NodeRuntimes = StaticMap<Node*, StaticArray<const RuntimeInfo*, cMaxNumNodeRuntimes>, cMaxNumInstances>;
enum class ScheduleDecision { eScheduled, eSkipManifest, eError };

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use Aos enum to properly display it in log.
What does eSkipManifest mean?


struct ScheduleResult {

Check failure on line 61 in src/core/cm/launcher/balancer.hpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Make sure that moving an object of class "ScheduleResult" is "noexcept" (for instance, by ensuring that moving base classes and member data is "noexcept").

See more on https://sonarcloud.io/project/issues?id=aosedge_aos_core_lib_cpp&issues=AZ5PFWpdLY4tfplsDiOy&open=AZ5PFWpdLY4tfplsDiOy&pullRequest=572
ScheduleDecision mResult;
Error mError;
};

static constexpr size_t cScheduleInstanceSize
= sizeof(oci::ImageIndex) + sizeof(StaticArray<Node*, cMaxNumNodes>) + sizeof(NodeRuntimes);
Expand All @@ -66,7 +72,8 @@

Error PerformNodeBalancing(Array<SharedPtr<Instance>>& instances);

Error ScheduleInstance(SharedPtr<Instance>& instance, const oci::IndexContentDescriptor& imageDescriptor);
ScheduleResult TryScheduleInstance(SharedPtr<Instance>& instance,
const oci::IndexContentDescriptor& imageDescriptor, Pair<Node*, const RuntimeInfo*>& nodeRuntime);

// Selects nodes
Error SelectNodes(Instance& instance, Array<Node*>& nodes);
Expand All @@ -75,7 +82,7 @@
void FilterNodesByResources(Instance& instance, Array<Node*>& nodes);

// Selects runtime
RetWithError<Pair<Node*, const RuntimeInfo*>> SelectRuntime(Instance& instance, Array<Node*>& nodes);
ScheduleResult SelectRuntime(Instance& instance, Array<Node*>& nodes, Pair<Node*, const RuntimeInfo*>& nodeRuntime);

Error CreateRuntimes(Array<Node*>& nodes, NodeRuntimes& runtimes);

Expand Down
Loading