Skip to content
103 changes: 40 additions & 63 deletions src/core/cm/launcher/balancer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,65 +26,72 @@ void Balancer::Init(InstanceManager& instanceManager, imagemanager::ItemInfoProv
mNetworkManager = &networkManager;
}

Error Balancer::RunInstances(UniqueLock<Mutex>& lock, bool rebalancing)
Error Balancer::RunInstances(UniqueLock<Mutex>& lock, Array<SharedPtr<Instance>>& instances, bool rebalancing)
{
if (auto err = PrepareForBalancing(rebalancing); !err.IsNone()) {
return AOS_ERROR_WRAP(err);
}

if (rebalancing) {
if (auto err = PerformPolicyBalancing(); !err.IsNone()) {
if (auto err = PerformPolicyBalancing(instances); !err.IsNone()) {
return AOS_ERROR_WRAP(err);
}
}

if (auto err = PerformNodeBalancing(); !err.IsNone()) {
if (auto err = PerformNodeBalancing(instances); !err.IsNone()) {
return AOS_ERROR_WRAP(err);
}

if (auto err = UpdateNetwork(); !err.IsNone()) {
return AOS_ERROR_WRAP(err);
}

// Submit scheduled instances before sending instances to nodes.
// So following status updates will change active instances.
if (auto err = mInstanceManager->SubmitScheduledInstances(); !err.IsNone()) {
return AOS_ERROR_WRAP(err);
}

if (auto err = mNodeManager->SendScheduledInstances(lock); !err.IsNone()) {
if (auto err = mNodeManager->SendScheduledInstances(
lock, mInstanceManager->GetActiveInstances(), mInstanceManager->GetRunningInstances());
!err.IsNone()) {
return AOS_ERROR_WRAP(err);
}

return ErrorEnum::eNone;
}

Error Balancer::LoadInstances()
Error Balancer::LoadSMDataForActiveInstances()
{
PrepareForBalancing(false);

auto err = mNodeManager->LoadInstances(mInstanceManager->GetActiveInstances(), mImageInfoProvider);
if (!err.IsNone()) {
if (auto err = PrepareForBalancing(false); !err.IsNone()) {
return AOS_ERROR_WRAP(err);
}

auto loadErr

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.

if (auto err =

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I prefer "out of if clause" initialization for long expressions.

= mNodeManager->LoadSMDataForActiveInstances(mInstanceManager->GetActiveInstances(), mImageInfoProvider);
if (!loadErr.IsNone()) {
return AOS_ERROR_WRAP(loadErr);
}

return ErrorEnum::eNone;
}

/***********************************************************************************************************************
* Private
**********************************************************************************************************************/

Error Balancer::PerformNodeBalancing()
Error Balancer::PerformNodeBalancing(Array<SharedPtr<Instance>>& instances)
{
LOG_DBG() << "Perform node balancing" << Log::Field("numNodes", mNodeManager->GetNodes().Size())
<< Log::Field("numInstances", mInstanceManager->GetScheduledInstances().Size());
<< Log::Field("numInstances", instances.Size());

for (const auto& instance : mInstanceManager->GetScheduledInstances()) {
for (auto& instance : instances) {
const auto& info = instance->GetInfo();
const auto& id = info.mInstanceIdent;

LOG_DBG() << "Perform node balancing" << Log::Field("instance", id);

if (mNodeManager->IsScheduled(id)) {
if (mInstanceManager->IsScheduled(id)) {
LOG_DBG() << "Instance aready scheduled" << Log::Field("instance", id);

continue;
Expand All @@ -95,6 +102,7 @@ Error Balancer::PerformNodeBalancing()
if (auto err = mImageInfoProvider.GetImageIndex(id.mItemID, info.mVersion, *imageIndex); !err.IsNone()) {
LOG_ERR() << "Can't get images" << Log::Field("instance", id) << Log::Field(err);

mInstanceManager->ScheduleInstance(instance, AOS_ERROR_WRAP(err));
continue;
}

Expand All @@ -104,7 +112,7 @@ Error Balancer::PerformNodeBalancing()
LOG_DBG() << "Try to schedule instance" << Log::Field("instance", id)
<< Log::Field("manifest", manifest.mDigest);

if (auto err = ScheduleInstance(*instance, manifest); err.IsNone()) {
if (auto err = ScheduleInstance(instance, manifest); err.IsNone()) {
LOG_DBG() << "Instance scheduled successfully" << Log::Field("nodeID", info.mNodeID);

break;
Expand All @@ -116,21 +124,20 @@ Error Balancer::PerformNodeBalancing()
}

if (!scheduleErr.IsNone()) {
instance->SetError(scheduleErr);
mInstanceManager->ScheduleInstance(instance, scheduleErr);
}
}

return ErrorEnum::eNone;
}

Error Balancer::ScheduleInstance(Instance& instance, const oci::IndexContentDescriptor& imageDescriptor)
Error Balancer::ScheduleInstance(SharedPtr<Instance>& instance, const oci::IndexContentDescriptor& imageDescriptor)
{
auto nodes = MakeUnique<StaticArray<Node*, cMaxNumNodes>>(&mAllocator);
auto instanceInfo = MakeUnique<aos::InstanceInfo>(&mAllocator);
auto nodes = MakeUnique<StaticArray<Node*, cMaxNumNodes>>(&mAllocator);

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

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

Expand All @@ -139,11 +146,11 @@ Error Balancer::ScheduleInstance(Instance& instance, const oci::IndexContentDesc
return AOS_ERROR_WRAP(Error(err, "get connected nodes failed"));
}

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

auto [nodeRuntime, selectErr] = SelectRuntime(instance, *nodes);
auto [nodeRuntime, selectErr] = SelectRuntime(*instance, *nodes);
if (!selectErr.IsNone()) {
return AOS_ERROR_WRAP(Error(selectErr, "can't find runtime for instance"));
}
Expand All @@ -152,7 +159,7 @@ Error Balancer::ScheduleInstance(Instance& instance, const oci::IndexContentDesc
auto& node = nodeRuntime.mFirst;
const auto& runtime = nodeRuntime.mSecond;

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

Expand Down Expand Up @@ -395,22 +402,10 @@ Error Balancer::RemoveNetworkForDeletedInstances()

for (const auto& instance : mInstanceManager->GetActiveInstances()) {
bool isScheduled = scheduledInstances.ContainsIf(
[&instance](const SharedPtr<Instance>& stashInst) { return stashInst.Get() == instance.Get(); });
[&instance](const SharedPtr<Instance>& schedInst) { return schedInst.Get() == instance.Get(); });

if (!isScheduled) {
const auto& info = instance->GetInfo();

if (info.mNodeID.IsEmpty()) {
// Instance has not been sent to any node(failed to schedule)
continue;
}

auto node = mNodeManager->FindNode(info.mNodeID);
if (!node) {
return AOS_ERROR_WRAP(ErrorEnum::eNotFound);
}

if (auto err = node->RemoveNetworkParams(info.mInstanceIdent, *mNetworkManager); !err.IsNone()) {
if (auto err = instance->RemoveNetworkParams(); !err.IsNone()) {
return AOS_ERROR_WRAP(err);
}
}
Expand All @@ -422,21 +417,7 @@ Error Balancer::RemoveNetworkForDeletedInstances()
Error Balancer::SetNetworkParams(bool onlyWithExposedPorts)
{
for (auto& instance : mInstanceManager->GetScheduledInstances()) {
const auto& id = instance->GetInfo().mInstanceIdent;

if (instance->GetInfo().mNodeID.IsEmpty()) {
continue;
}

auto node = mNodeManager->FindNode(instance->GetStatus().mNodeID);
if (!node) {
LOG_ERR() << "Can't find node for instance" << Log::Field("instance", id)
<< Log::Field("nodeID", instance->GetStatus().mNodeID);

continue;
}

auto err = node->SetupNetworkParams(id, onlyWithExposedPorts, *mNetworkManager);
auto err = instance->PrepareNetworkParams(onlyWithExposedPorts);
if (!err.IsNone()) {
instance->SetError(AOS_ERROR_WRAP(Error(err, "can't setup network params")));

Expand Down Expand Up @@ -470,12 +451,11 @@ Error Balancer::SetupNetworkForNewInstances()
return ErrorEnum::eNone;
}

Error Balancer::PerformPolicyBalancing()
Error Balancer::PerformPolicyBalancing(Array<SharedPtr<Instance>>& instances)
{
auto imageIndex = MakeUnique<oci::ImageIndex>(&mAllocator);
auto instanceInfo = MakeUnique<aos::InstanceInfo>(&mAllocator);
auto imageIndex = MakeUnique<oci::ImageIndex>(&mAllocator);

for (const auto& instance : mInstanceManager->GetScheduledInstances()) {
for (auto& instance : instances) {
const auto& info = instance->GetInfo();
const auto& id = info.mInstanceIdent;
const auto& version = info.mVersion;
Expand Down Expand Up @@ -528,18 +508,15 @@ Error Balancer::PerformPolicyBalancing()

auto node = mNodeManager->FindNode(info.mNodeID);
if (!node) {
LOG_ERR() << "Can't find node for instance" << Log::Field("instance", id)
LOG_WRN() << "Can't find node for instance" << Log::Field("instance", id)
<< Log::Field("nodeID", info.mNodeID);

instance->SetError(AOS_ERROR_WRAP(ErrorEnum::eFailed));

continue;
}

if (auto err = instance->Schedule(*node, info.mRuntimeID, *instanceInfo); !err.IsNone()) {
LOG_ERR() << "Can't schedule instance" << Log::Field("instance", id) << Log::Field(err);
if (auto err = mInstanceManager->ScheduleInstance(instance, *node, info.mRuntimeID); !err.IsNone()) {
LOG_WRN() << "Can't schedule instance" << Log::Field("instance", id) << Log::Field(AOS_ERROR_WRAP(err));

instance->SetError(err);
continue;
}
}

Expand Down
25 changes: 14 additions & 11 deletions src/core/cm/launcher/balancer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,27 +47,30 @@ class Balancer {
* @param rebalancing flag indicating rebalancing.
* @return Error.
*/
Error RunInstances(UniqueLock<Mutex>& lock, bool rebalancing);
Error RunInstances(UniqueLock<Mutex>& lock, Array<SharedPtr<Instance>>& instances, bool rebalancing);

/**
* Loads instances from storage.
* Loads Service Manager (SM) data for active instances that were loaded from storage.
*
* @return Error.
*/
Error LoadInstances();
Error LoadSMDataForActiveInstances();

private:
using NodeRuntimes = StaticMap<Node*, StaticArray<const RuntimeInfo*, cMaxNumNodeRuntimes>, cMaxNumInstances>;

static constexpr auto cAllocatorSize = sizeof(StaticArray<RunInstanceRequest, cMaxNumInstances>)
+ sizeof(StaticArray<Node*, cMaxNumNodes>) + sizeof(oci::ItemConfig) + sizeof(oci::ImageConfig)
+ sizeof(oci::ImageIndex) + sizeof(aos::cm::networkmanager::NetworkServiceData) + sizeof(aos::InstanceInfo)
+ sizeof(StaticMap<Node*, StaticArray<const RuntimeInfo*, cMaxNumNodeRuntimes>, cMaxNumInstances>)
+ sizeof(StaticArray<StaticString<cIDLen>, cMaxNumInstances>);
static constexpr size_t cScheduleInstanceSize
= sizeof(oci::ImageIndex) + sizeof(StaticArray<Node*, cMaxNumNodes>) + sizeof(NodeRuntimes);
static constexpr size_t cPolicyBalancingSize = sizeof(oci::ImageIndex);
static constexpr size_t cNetworkSetupSize = sizeof(StaticArray<StaticString<cIDLen>, cMaxNumInstances>);
static constexpr size_t cMonitoringSize = sizeof(monitoring::NodeMonitoringData);

Error PerformNodeBalancing();
static constexpr size_t cAllocatorSize
= Max(cScheduleInstanceSize, cPolicyBalancingSize, cNetworkSetupSize, cMonitoringSize);

Error ScheduleInstance(Instance& instance, const oci::IndexContentDescriptor& imageDescriptor);
Error PerformNodeBalancing(Array<SharedPtr<Instance>>& instances);

Error ScheduleInstance(SharedPtr<Instance>& instance, const oci::IndexContentDescriptor& imageDescriptor);

// Selects nodes
Error SelectNodes(Instance& instance, Array<Node*>& nodes);
Expand All @@ -94,7 +97,7 @@ class Balancer {
Error SetNetworkParams(bool onlyWithExposedPorts);
Error SetupNetworkForNewInstances();

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

Error PrepareForBalancing(bool rebalancing);
void UpdateMonitoringData();
Expand Down
Loading
Loading