Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add node resource availability #378

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
980468a
initial commit
HorjuRares Sep 12, 2024
7c8846a
Add Resource Measurement
HorjuRares Sep 13, 2024
f19d6e1
More useless things
HorjuRares Sep 17, 2024
10acac6
Delete agent/src/resource_measurement/resource_measurement_sender
HorjuRares Sep 17, 2024
d52f8d1
Sending of AgentResource
HorjuRares Sep 17, 2024
2cb7343
Add the actual measurement
HorjuRares Sep 18, 2024
e953922
Add data load to resource availability message
HorjuRares Sep 19, 2024
b3c0b46
Add resource availability in ank get agents
HorjuRares Sep 20, 2024
1642df2
Measure only free memory
HorjuRares Sep 23, 2024
e8f1924
Finish impl and start adding unit tests
HorjuRares Sep 26, 2024
eba7e62
Add unit tests
HorjuRares Sep 26, 2024
dc80538
Fix unit tests
HorjuRares Sep 27, 2024
381d54f
Update documentation
HorjuRares Sep 30, 2024
db90f29
Rename node resource availability message
HorjuRares Oct 1, 2024
8f0516f
Merge branch 'main' into 282_node_resource_availability
HorjuRares Oct 1, 2024
217f9f5
Merge branch 'eclipse-ankaios:main' into 282_node_resource_availability
HorjuRares Oct 1, 2024
d37599b
Update AgentMap
HorjuRares Oct 7, 2024
8a9a2ab
Fix failing unit tests
HorjuRares Oct 7, 2024
bad40bc
Update docs
HorjuRares Oct 7, 2024
3574b0f
Update ank/doc/swdesign/README.md
HorjuRares Oct 7, 2024
fc740de
Merge branch 'eclipse-ankaios:main' into 282_node_resource_availability
HorjuRares Oct 7, 2024
7552bc2
Update resource availability swdd
HorjuRares Oct 7, 2024
aff5340
Update agent resource availability swdd
HorjuRares Oct 7, 2024
026d059
Update agent manager unit tests
HorjuRares Oct 8, 2024
333d1ad
Refactor the node resource availability
HorjuRares Oct 9, 2024
ae3b096
Update doc and test cases
HorjuRares Oct 10, 2024
7fd17ec
Update server/doc/swdesign/README.md
HorjuRares Oct 10, 2024
b95ce56
Update filtering
HorjuRares Oct 10, 2024
5e2e217
Update filtering
HorjuRares Oct 10, 2024
c363453
Update stests and documentation
HorjuRares Oct 11, 2024
8afc34a
Apply suggestions from code review - Documentation
HorjuRares Oct 14, 2024
7887aec
Update docs and agent_manager
HorjuRares Oct 14, 2024
2e854a7
Update server/doc/swdesign/README.md
HorjuRares Oct 14, 2024
178548f
Update server/doc/swdesign/README.md
HorjuRares Oct 14, 2024
0ec9807
Fix match assertion and PERCENTAGE_BASE
HorjuRares Oct 14, 2024
5174275
Improve get agents readability
HorjuRares Oct 14, 2024
1510706
Update doc
HorjuRares Oct 14, 2024
31851b6
Rename CpuLoad to CpuUsage
HorjuRares Oct 14, 2024
49b777b
Update requirements versions
HorjuRares Oct 15, 2024
7ec20dc
Update messages
HorjuRares Oct 15, 2024
85d09e6
Fix CLI format and trace messages
HorjuRares Oct 15, 2024
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
2 changes: 1 addition & 1 deletion agent/doc/swdesign/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2764,7 +2764,7 @@ Needs:

Status: approved

At an interval of 2 seconds, the AgentManager measures the global CPU load and the available free memory and sends them to the Ankaios server via an `AgentLoadStatus` message.
At an interval of 2 seconds, the AgentManager measures the global CPU usage and the available free memory and sends them to the Ankaios server via an `AgentLoadStatus` message.

Rationale:
Available resources must be available in the cluster in order to enable dynamic scheduling, e.g., done by a workload.
Expand Down
14 changes: 7 additions & 7 deletions agent/src/agent_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use sysinfo::{CpuRefreshKind, MemoryRefreshKind, RefreshKind, System};
use common::{
commands::AgentLoadStatus,
from_server_interface::{FromServer, FromServerReceiver},
objects::{CpuLoad, FreeMemory, WorkloadState},
objects::{CpuUsage, FreeMemory, WorkloadState},
std_extensions::{GracefulExitResult, IllegalStateResult},
to_server_interface::{ToServerInterface, ToServerSender},
};
Expand Down Expand Up @@ -214,20 +214,20 @@ impl AgentManager {

sys.refresh_all();

let cpu_load = sys.global_cpu_usage();
let cpu_usage = sys.global_cpu_usage();
let free_memory = sys.free_memory();

log::trace!(
"Agent '{}' reports resource usage: CPU Load: {:.2}%, Free Memory: {} B",
"Agent '{}' reports resource usage: CPU Usage: {:.2}%, Free Memory: {} B",
self.agent_name,
cpu_load,
cpu_usage,
free_memory,
);

self.to_server
.agent_load_status(AgentLoadStatus {
agent_name: self.agent_name.clone(),
cpu_load: CpuLoad::new(cpu_load),
cpu_usage: CpuUsage::new(cpu_usage),
free_memory: FreeMemory { free_memory },
})
.await
Expand Down Expand Up @@ -580,8 +580,8 @@ mod tests {
let result = server_receiver.recv().await.unwrap();
if let ToServer::AgentLoadStatus(load_status) = result {
assert_eq!(load_status.agent_name, AGENT_NAME.to_string());
assert_ne!(load_status.cpu_load.cpu_load, 0);
assert_ne!(load_status.cpu_load.cpu_load, 0);
assert_ne!(load_status.cpu_usage.cpu_usage, 0);
assert_ne!(load_status.cpu_usage.cpu_usage, 0);
} else {
panic!("Expected AgentLoadStatus, got something else");
}
Expand Down
2 changes: 1 addition & 1 deletion agent/src/runtime_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1950,7 +1950,7 @@ mod tests {
agents: HashMap::from([(
AGENT_NAME.to_owned(),
objects::AgentAttributes {
cpu_load: Some(objects::CpuLoad { cpu_load: 42 }),
cpu_usage: Some(objects::CpuUsage { cpu_usage: 42 }),
free_memory: Some(objects::FreeMemory { free_memory: 42 }),
}
.into(),
Expand Down
6 changes: 3 additions & 3 deletions ank/doc/swdesign/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -903,9 +903,9 @@ Status: approved

When the Ankaios CLI presents connected Ankaios agents to the user, the Ankaios CLI shall present the agents as rows in a table with the following content:

| NAME | WORKLOADS | CPU USAGE | FREE MEMORY |
| ------------------------ | -------------------------------- | ------------------------ | -------------------------------- |
| `<agent_name>` as text | `<assigned_workloads>` as number | `<cpu_usage>` as load in percent | `<free_memory>` in bytes |
| NAME | WORKLOADS | CPU USAGE | FREE MEMORY |
| ------------------------ | -------------------------------- | -------------------------------- | -------------------------------- |
| `<agent_name>` as text | `<assigned_workloads>` as number | `<cpu_usage>` as load in percent | `<free_memory>` in bytes |

Tags:
- CliCommands
Expand Down
4 changes: 2 additions & 2 deletions ank/src/cli_commands/agent_table_row.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ pub struct AgentTableRow {
pub agent_name: String,
#[tabled(rename = "WORKLOADS")]
pub workloads: u32,
#[tabled(rename = "CPU LOAD")]
pub cpu_load: String,
#[tabled(rename = "CPU USAGE")]
pub cpu_usage: String,
#[tabled(rename = "FREE MEMORY")]
pub free_memory: String,
}
22 changes: 11 additions & 11 deletions ank/src/cli_commands/get_agents.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ fn transform_into_table_rows(
AgentTableRow {
agent_name,
workloads: workload_states_count,
cpu_load: agent_attributes.get_cpu_load_as_string(),
cpu_usage: agent_attributes.get_cpu_usage_as_string(),
free_memory: agent_attributes.get_free_memory_as_string(),
}
})
Expand Down Expand Up @@ -142,9 +142,9 @@ mod tests {
let table_output_result = cmd.get_agents().await;

let expected_table_output = [
"NAME WORKLOADS CPU LOAD FREE MEMORY",
"agent_A 1 0.42 % 42 B ",
"agent_B 1 0.42 % 42 B ",
"NAME WORKLOADS CPU USAGE FREE MEMORY",
"agent_A 1 42 % 42 B ",
"agent_B 1 42 % 42 B ",
]
.join("\n");

Expand Down Expand Up @@ -179,7 +179,7 @@ mod tests {

let table_output_result = cmd.get_agents().await;

let expected_table_output = "NAME WORKLOADS CPU LOAD FREE MEMORY".to_string();
let expected_table_output = "NAME WORKLOADS CPU USAGE FREE MEMORY".to_string();

assert_eq!(Ok(expected_table_output), table_output_result);
}
Expand Down Expand Up @@ -207,8 +207,8 @@ mod tests {
let table_output_result = cmd.get_agents().await;

let expected_table_output = [
"NAME WORKLOADS CPU LOAD FREE MEMORY",
"agent_A 0 0.42 % 42 B ",
"NAME WORKLOADS CPU USAGE FREE MEMORY",
"agent_A 0 42 % 42 B ",
]
.join("\n");

Expand Down Expand Up @@ -273,8 +273,8 @@ mod tests {
let table_output_result = cmd.get_agents().await;

let expected_table_output = [
"NAME WORKLOADS CPU LOAD FREE MEMORY",
"agent_A 1 0.42 % 42 B ",
"NAME WORKLOADS CPU USAGE FREE MEMORY",
"agent_A 1 42 % 42 B ",
]
.join("\n");

Expand Down Expand Up @@ -310,8 +310,8 @@ mod tests {
let table_output_result = cmd.get_agents().await;

let expected_table_output = [
"NAME WORKLOADS CPU LOAD FREE MEMORY",
"agent_A 1 0.42 % 42 B ",
"NAME WORKLOADS CPU USAGE FREE MEMORY",
"agent_A 1 42 % 42 B ",
]
.join("\n");

Expand Down
46 changes: 13 additions & 33 deletions ank/src/filtered_complete_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@ use serde::{Deserialize, Serialize, Serializer};

use crate::{output_and_error, output_warn};

const PERCENTAGE_BASE: u32 = 100;

pub fn serialize_option_to_ordered_map<S, T: Serialize>(
value: &Option<HashMap<String, T>>,
serializer: S,
Expand All @@ -41,20 +39,6 @@ where
}
}

pub fn serialize_percent_as_proportion<S>(
value: &Option<u32>,
serializer: S,
) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
if let Some(value) = value {
serializer.serialize_f32((*value as f32) / (PERCENTAGE_BASE as f32))
} else {
serializer.serialize_none()
}
}

#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct FilteredCompleteState {
Expand Down Expand Up @@ -92,9 +76,9 @@ pub struct FilteredAgentMap {

#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize, Default)]
#[serde(rename_all = "camelCase")]
pub struct FilteredCpuLoad {
#[serde(serialize_with = "serialize_percent_as_proportion")]
pub cpu_load: Option<u32>,
pub struct FilteredCpuUsage {
#[serde(skip_serializing_if = "Option::is_none")]
pub cpu_usage: Option<u32>,
}

#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize, Default)]
Expand All @@ -108,20 +92,16 @@ pub struct FilteredFreeMemory {
#[serde(rename_all = "camelCase")]
pub struct FilteredAgentAttributes {
#[serde(skip_serializing_if = "Option::is_none")]
pub cpu_load: Option<FilteredCpuLoad>,
pub cpu_usage: Option<FilteredCpuUsage>,
#[serde(skip_serializing_if = "Option::is_none")]
pub free_memory: Option<FilteredFreeMemory>,
}

impl FilteredAgentAttributes {
pub fn get_cpu_load_as_string(&mut self) -> String {
if let Some(cpu_load) = &self.cpu_load {
if let Some(cpu_load_value) = cpu_load.cpu_load {
format!(
"{}.{} %",
cpu_load_value / PERCENTAGE_BASE,
cpu_load_value % PERCENTAGE_BASE
)
pub fn get_cpu_usage_as_string(&mut self) -> String {
if let Some(cpu_usage) = &self.cpu_usage {
if let Some(cpu_usage_value) = cpu_usage.cpu_usage {
format!("{} %", cpu_usage_value)
} else {
"".to_string()
}
Expand Down Expand Up @@ -258,16 +238,16 @@ impl From<ank_base::AgentMap> for FilteredAgentMap {
impl From<ank_base::AgentAttributes> for FilteredAgentAttributes {
fn from(value: ank_base::AgentAttributes) -> Self {
FilteredAgentAttributes {
cpu_load: value.cpu_load.map(Into::into),
cpu_usage: value.cpu_usage.map(Into::into),
free_memory: value.free_memory.map(Into::into),
}
}
}

impl From<ank_base::CpuLoad> for FilteredCpuLoad {
fn from(value: ank_base::CpuLoad) -> Self {
FilteredCpuLoad {
cpu_load: Some(value.cpu_load),
impl From<ank_base::CpuUsage> for FilteredCpuUsage {
fn from(value: ank_base::CpuUsage) -> Self {
FilteredCpuUsage {
cpu_usage: Some(value.cpu_usage),
}
}
}
Expand Down
8 changes: 4 additions & 4 deletions api/proto/ank_base.proto
Original file line number Diff line number Diff line change
Expand Up @@ -199,10 +199,10 @@ message AgentMap {
}

/**
* A message containing the CPU load information of the agent.
* A message containing the CPU usage information of the agent.
*/
message CpuLoad {
uint32 cpu_load = 1; // expressed in percent, the formula for calculating: cpu_load = (new_work_time - old_work_time) / (new_total_time - old_total_time) * 100
message CpuUsage {
uint32 cpu_usage = 1; // expressed in percent, the formula for calculating: cpu_usage = (new_work_time - old_work_time) / (new_total_time - old_total_time) * 100
}

/**
Expand All @@ -216,7 +216,7 @@ message FreeMemory {
* A message that contains attributes of the agent.
*/
message AgentAttributes {
CpuLoad cpu_load = 1; /// The cpu load of the agent.
CpuUsage cpu_usage = 1; /// The cpu usage of the agent.
FreeMemory free_memory = 2; /// The amount of free memory of the agent.
}

Expand Down
4 changes: 2 additions & 2 deletions common/src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
//
// SPDX-License-Identifier: Apache-2.0

use crate::objects::{CompleteState, CpuLoad, DeletedWorkload, FreeMemory, WorkloadSpec};
use crate::objects::{CompleteState, CpuUsage, DeletedWorkload, FreeMemory, WorkloadSpec};
use api::ank_base;
use serde::{Deserialize, Serialize};

Expand All @@ -24,7 +24,7 @@ pub struct AgentHello {
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct AgentLoadStatus {
pub agent_name: String,
pub cpu_load: CpuLoad,
pub cpu_usage: CpuUsage,
pub free_memory: FreeMemory,
}

Expand Down
44 changes: 21 additions & 23 deletions common/src/objects/agent_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,15 @@ use crate::commands;

type AgentName = String;

pub const PERCENTAGE_BASE: f32 = 100.0;

#[derive(Debug, Serialize, Deserialize, Clone, Default, PartialEq, Eq)]
pub struct CpuLoad {
pub cpu_load: u32,
pub struct CpuUsage {
pub cpu_usage: u32,
}

impl CpuLoad {
pub fn new(cpu_load: f32) -> Self {
impl CpuUsage {
pub fn new(cpu_usage: f32) -> Self {
Self {
cpu_load: (cpu_load * PERCENTAGE_BASE).trunc() as u32,
cpu_usage: cpu_usage.round() as u32,
}
}
}
Expand All @@ -42,7 +40,7 @@ pub struct FreeMemory {

#[derive(Debug, Serialize, Deserialize, Clone, Default, PartialEq, Eq)]
pub struct AgentAttributes {
pub cpu_load: Option<CpuLoad>,
pub cpu_usage: Option<CpuUsage>,
pub free_memory: Option<FreeMemory>,
}

Expand All @@ -65,24 +63,24 @@ impl AgentMap {

pub fn update_resource_availability(&mut self, agent_load_status: commands::AgentLoadStatus) {
self.0.entry(agent_load_status.agent_name).and_modify(|e| {
e.cpu_load = Some(agent_load_status.cpu_load);
e.cpu_usage = Some(agent_load_status.cpu_usage);
e.free_memory = Some(agent_load_status.free_memory);
});
}
}

impl From<CpuLoad> for ank_base::CpuLoad {
fn from(item: CpuLoad) -> ank_base::CpuLoad {
ank_base::CpuLoad {
cpu_load: item.cpu_load,
impl From<CpuUsage> for ank_base::CpuUsage {
fn from(item: CpuUsage) -> ank_base::CpuUsage {
ank_base::CpuUsage {
cpu_usage: item.cpu_usage,
}
}
}

impl From<ank_base::CpuLoad> for CpuLoad {
fn from(item: ank_base::CpuLoad) -> Self {
CpuLoad {
cpu_load: item.cpu_load,
impl From<ank_base::CpuUsage> for CpuUsage {
fn from(item: ank_base::CpuUsage) -> Self {
CpuUsage {
cpu_usage: item.cpu_usage,
}
}
}
Expand All @@ -106,8 +104,8 @@ impl From<ank_base::FreeMemory> for FreeMemory {
impl From<AgentAttributes> for ank_base::AgentAttributes {
fn from(item: AgentAttributes) -> ank_base::AgentAttributes {
ank_base::AgentAttributes {
cpu_load: Some(ank_base::CpuLoad {
cpu_load: item.cpu_load.unwrap_or_default().cpu_load,
cpu_usage: Some(ank_base::CpuUsage {
cpu_usage: item.cpu_usage.unwrap_or_default().cpu_usage,
}),
free_memory: Some(ank_base::FreeMemory {
free_memory: item.free_memory.unwrap_or_default().free_memory,
Expand All @@ -119,8 +117,8 @@ impl From<AgentAttributes> for ank_base::AgentAttributes {
impl From<ank_base::AgentAttributes> for AgentAttributes {
fn from(item: ank_base::AgentAttributes) -> Self {
AgentAttributes {
cpu_load: Some(CpuLoad {
cpu_load: item.cpu_load.unwrap_or_default().cpu_load,
cpu_usage: Some(CpuUsage {
cpu_usage: item.cpu_usage.unwrap_or_default().cpu_usage,
}),
free_memory: Some(FreeMemory {
free_memory: item.free_memory.unwrap_or_default().free_memory,
Expand Down Expand Up @@ -170,7 +168,7 @@ pub fn generate_test_agent_map(agent_name: impl Into<String>) -> AgentMap {
agent_map
.entry(agent_name.into())
.or_insert(AgentAttributes {
cpu_load: Some(CpuLoad { cpu_load: 42 }),
cpu_usage: Some(CpuUsage { cpu_usage: 42 }),
free_memory: Some(FreeMemory { free_memory: 42 }),
});
agent_map
Expand All @@ -185,7 +183,7 @@ pub fn generate_test_agent_map_from_specs(workloads: &[crate::objects::WorkloadS
agent_map
.entry(agent_name.to_owned())
.or_insert(AgentAttributes {
cpu_load: Some(CpuLoad { cpu_load: 42 }),
cpu_usage: Some(CpuUsage { cpu_usage: 42 }),
free_memory: Some(FreeMemory { free_memory: 42 }),
});
agent_map
Expand Down
2 changes: 1 addition & 1 deletion common/src/objects/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ pub use complete_state::CompleteState;
mod agent_map;
#[cfg(any(feature = "test_utils", test))]
pub use agent_map::{generate_test_agent_map, generate_test_agent_map_from_specs};
pub use agent_map::{AgentAttributes, AgentMap, CpuLoad, FreeMemory};
pub use agent_map::{AgentAttributes, AgentMap, CpuUsage, FreeMemory};

mod workload_states_map;
pub use workload_states_map::WorkloadStatesMap;
Expand Down
Loading