Skip to content

Commit

Permalink
feat(hydro_deploy)!: Perf works over SSH (#1313)
Browse files Browse the repository at this point in the history
See documentation on how to use in
[Notion](https://www.notion.so/hydro-project/perf-Measuring-CPU-usage-6135b6ce56a94af38eeeba0a55deef9c).

Fix #1353

BREAKING CHANGE: changes some config arguments

---------

Co-authored-by: Mingwei Samuel <mingwei.samuel@gmail.com>
  • Loading branch information
davidchuyaya and MingweiSamuel authored Jul 29, 2024
1 parent 654b77d commit 749a103
Show file tree
Hide file tree
Showing 19 changed files with 168 additions and 42 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ perf.data.old
flamegraph.svg

/rustc-ice-*.txt
/*.perf.data*
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion hydro_deploy/core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ dyn-clone = "1"
futures = "0.3.26"
futures-core = "0.3.26"
hydroflow_cli_integration = { path = "../hydroflow_cli_integration", version = "^0.5.2" }
indicatif = "0.17.6"
indicatif = "0.17.8"
memo-map = "0.3.2"
nanoid = "0.4.0"
nix = "0.26.2"
Expand Down
16 changes: 13 additions & 3 deletions hydro_deploy/core/src/deployment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ impl Deployment {
self.add_host(LocalhostHost::new)
}

#[allow(non_snake_case)]
#[allow(non_snake_case, clippy::too_many_arguments)] // TODO(mingwei)
pub fn GcpComputeEngineHost(
&mut self,
project: impl Into<String>,
Expand All @@ -40,9 +40,19 @@ impl Deployment {
region: impl Into<String>,
network: Arc<RwLock<GcpNetwork>>,
user: Option<String>,
startup_script: Option<String>,
) -> Arc<GcpComputeEngineHost> {
self.add_host(|id| {
GcpComputeEngineHost::new(id, project, machine_type, image, region, network, user)
GcpComputeEngineHost::new(
id,
project,
machine_type,
image,
region,
network,
user,
startup_script,
)
})
}

Expand Down Expand Up @@ -109,7 +119,7 @@ impl Deployment {
.collect::<Vec<_>>();

futures::stream::iter(services_future)
.buffer_unordered(8)
.buffer_unordered(16)
.try_fold((), |_, _| async { Ok(()) })
})
.await?;
Expand Down
7 changes: 6 additions & 1 deletion hydro_deploy/core/src/gcp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,11 +176,13 @@ pub struct GcpComputeEngineHost {
pub region: String,
pub network: Arc<RwLock<GcpNetwork>>,
pub user: Option<String>,
pub startup_script: Option<String>,
pub launched: OnceLock<Arc<LaunchedComputeEngine>>,
external_ports: Mutex<Vec<u16>>,
}

impl GcpComputeEngineHost {
#[allow(clippy::too_many_arguments)] // TODO(mingwei)
pub fn new(
id: usize,
project: impl Into<String>,
Expand All @@ -189,6 +191,7 @@ impl GcpComputeEngineHost {
region: impl Into<String>,
network: Arc<RwLock<GcpNetwork>>,
user: Option<String>,
startup_script: Option<String>,
) -> Self {
Self {
id,
Expand All @@ -198,6 +201,7 @@ impl GcpComputeEngineHost {
region: region.into(),
network,
user,
startup_script,
launched: OnceLock::new(),
external_ports: Mutex::new(Vec::new()),
}
Expand Down Expand Up @@ -412,7 +416,8 @@ impl Host for GcpComputeEngineHost {
]
}
],
"network_interface": external_interfaces
"network_interface": external_interfaces,
"metadata_startup_script": self.startup_script,
}),
);

Expand Down
8 changes: 6 additions & 2 deletions hydro_deploy/core/src/hydroflow_crate/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use std::path::PathBuf;
use std::sync::Arc;

use perf_options::PerfOptions;

use super::Host;
use crate::ServiceBuilder;

Expand All @@ -10,6 +12,8 @@ pub mod ports;
pub mod service;
pub use service::*;

pub mod perf_options;

#[derive(PartialEq)]
pub enum CrateTarget {
Default,
Expand All @@ -24,7 +28,7 @@ pub struct HydroflowCrate {
target: CrateTarget,
on: Arc<dyn Host>,
profile: Option<String>,
perf: Option<PathBuf>, /* If a path is provided, run perf to get CPU time and output to that path.perf.data */
perf: Option<PerfOptions>,
args: Vec<String>,
display_name: Option<String>,
}
Expand Down Expand Up @@ -78,7 +82,7 @@ impl HydroflowCrate {
self
}

pub fn perf(mut self, perf: impl Into<PathBuf>) -> Self {
pub fn perf(mut self, perf: impl Into<PerfOptions>) -> Self {
if self.perf.is_some() {
panic!("perf path already set");
}
Expand Down
7 changes: 7 additions & 0 deletions hydro_deploy/core/src/hydroflow_crate/perf_options.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
use std::path::PathBuf;

#[derive(Clone)]
pub struct PerfOptions {
pub output_file: PathBuf,
pub frequency: u32,
}
5 changes: 3 additions & 2 deletions hydro_deploy/core/src/hydroflow_crate/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use serde::Serialize;
use tokio::sync::{mpsc, RwLock};

use super::build::{build_crate_memoized, BuildError, BuildOutput, BuildParams};
use super::perf_options::PerfOptions;
use super::ports::{self, HydroflowPortConfig, HydroflowSink, SourcePath};
use crate::progress::ProgressTracker;
use crate::{
Expand All @@ -21,7 +22,7 @@ pub struct HydroflowCrateService {
id: usize,
pub(super) on: Arc<dyn Host>,
build_params: BuildParams,
perf: Option<PathBuf>,
perf: Option<PerfOptions>,
args: Option<Vec<String>>,
display_id: Option<String>,
external_ports: Vec<u16>,
Expand Down Expand Up @@ -54,7 +55,7 @@ impl HydroflowCrateService {
bin: Option<String>,
example: Option<String>,
profile: Option<String>,
perf: Option<PathBuf>,
perf: Option<PerfOptions>,
features: Option<Vec<String>>,
args: Option<Vec<String>>,
display_id: Option<String>,
Expand Down
4 changes: 2 additions & 2 deletions hydro_deploy/core/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
use std::collections::HashMap;
use std::net::SocketAddr;
use std::path::PathBuf;
use std::sync::Arc;

use anyhow::Result;
use async_trait::async_trait;
use hydroflow_cli_integration::ServerBindConfig;
use hydroflow_crate::perf_options::PerfOptions;

pub mod deployment;
pub use deployment::Deployment;
Expand Down Expand Up @@ -101,7 +101,7 @@ pub trait LaunchedHost: Send + Sync {
id: String,
binary: &BuildOutput,
args: &[String],
perf: Option<PathBuf>,
perf: Option<PerfOptions>,
) -> Result<Box<dyn LaunchedBinary>>;

async fn forward_port(&self, addr: &SocketAddr) -> Result<SocketAddr>;
Expand Down
19 changes: 13 additions & 6 deletions hydro_deploy/core/src/localhost/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use std::collections::HashMap;
use std::net::SocketAddr;
use std::path::PathBuf;
use std::sync::Arc;

use anyhow::{Context, Result};
Expand All @@ -13,6 +12,7 @@ use super::{
ResourceResult, ServerStrategy,
};
use crate::hydroflow_crate::build::BuildOutput;
use crate::hydroflow_crate::perf_options::PerfOptions;
use crate::HostStrategyGetter;

pub mod launched_binary;
Expand Down Expand Up @@ -150,15 +150,22 @@ impl LaunchedHost for LaunchedLocalhost {
id: String,
binary: &BuildOutput,
args: &[String],
perf: Option<PathBuf>,
perf: Option<PerfOptions>,
) -> Result<Box<dyn LaunchedBinary>> {
let mut command = if let Some(perf) = perf {
println!("Profiling binary with perf");
let mut tmp = Command::new("perf");
tmp.args(["record", "-F", "5", "--call-graph", "dwarf,64000", "-o"])
.arg(&perf)
.arg(&binary.bin_path)
.args(args);
tmp.args([
"record",
"-F",
&perf.frequency.to_string(),
"--call-graph",
"dwarf,64000",
"-o",
])
.arg(&perf.output_file)
.arg(&binary.bin_path)
.args(args);
tmp
} else {
let mut tmp = Command::new(&binary.bin_path);
Expand Down
Loading

0 comments on commit 749a103

Please sign in to comment.