Skip to content

Commit 27bb3b7

Browse files
committed
internal: Integrate new remote storage. (#2587)
* Add crate. * Start on http. * Add cache context. * Remove old code. * Move more code over. * Polish. * Fix tests. * Tier 2. * Tier 3. * Tier 4. * Polish. * Fix format. * Polish. * Add tests.
1 parent a3a8aa1 commit 27bb3b7

51 files changed

Lines changed: 3447 additions & 2298 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@
1111
- Improved our "stream and capture output" child process handling to operate on bytes instead of
1212
lines, which should resolve some edge cases with output not being written to the console, or
1313
being written out of order.
14+
- **Remote cache**
15+
- Added compression support for streamed read/writes of blobs (large files).
16+
- Added extensive testing to account for edge cases.
17+
- When the server doesn't support the configured compression, it will now default to "identity"
18+
(uncompressed) instead of disabling the cache entirely.
1419
- **VCS**
1520
- Hardened all executed Git commands: revisions are validated against argument injection,
1621
credential prompts now fail immediately instead of hanging, and the fsmonitor daemon is now

Cargo.lock

Lines changed: 38 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,24 +21,32 @@ clap = { version = "4.6.1", default-features = false, features = [
2121
"error-context",
2222
] }
2323
clap_complete = "4.6.5"
24-
compact_str = { version = "0.9.1", default-features = false, features = ["serde"] }
24+
compact_str = { version = "0.9.1", default-features = false, features = [
25+
"serde",
26+
] }
2527
convert_case = "0.11.0"
2628
criterion = { package = "codspeed-criterion-compat", version = "4.7.0", default-features = false, features = [
2729
"async_tokio",
2830
] }
2931
daggy = { version = "0.9.0", features = ["serde-1"] }
3032
dirs = "6.0.0"
3133
futures = "0.3.31"
34+
httpmock = "0.8.3"
3235
indexmap = "2.13.0"
3336
iocraft = "0.8.3"
3437
libc = "0.2.186"
3538
md5 = "0.8.0"
3639
miette = "7.6.0"
3740
num_cpus = "1.17.0"
3841
pathdiff = "0.2.3"
39-
petgraph = { version = "0.8.3", default-features = false, features = ["serde-1"] }
42+
petgraph = { version = "0.8.3", default-features = false, features = [
43+
"serde-1",
44+
] }
4045
relative-path = { version = "2.0.1" }
41-
regex = { version = "1.12.3", default-features = false, features = ["std", "perf"] }
46+
regex = { version = "1.12.3", default-features = false, features = [
47+
"std",
48+
"perf",
49+
] }
4250
reqwest = { version = "0.13.4", default-features = false, features = [
4351
"rustls",
4452
# We don't use openssl but its required for musl builds
@@ -47,7 +55,9 @@ reqwest = { version = "0.13.4", default-features = false, features = [
4755
once_cell = "1.21.4"
4856
rustc-hash = "2.1.1"
4957
scc = "3.7.1"
50-
schematic = { version = "0.19.7", default-features = false, features = ["schema"] }
58+
schematic = { version = "0.19.7", default-features = false, features = [
59+
"schema",
60+
] }
5161
serial_test = "3.4.0"
5262
semver = "1.0.27"
5363
serde = { version = "1.0.228", features = ["derive"] }

crates/actions/src/actions/sync_workspace.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ pub async fn sync_workspace(
2727
// Connect to the remote service in this action,
2828
// as it always runs before tasks, and we don't need it
2929
// for non-pipeline related features!
30+
app_context.cache_engine.storage.connect_backends().await?;
31+
3032
if app_context.workspace_config.remote.is_enabled() {
3133
RemoteService::connect(
3234
&app_context.workspace_config.remote,

crates/app/Cargo.toml

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ moon_api = { path = "../api" }
1515
moon_app_context = { path = "../app-context" }
1616
moon_app_macros = { path = "../app-macros" }
1717
moon_cache = { path = "../cache" }
18+
moon_cache_local = { path = "../cache-local" }
19+
moon_cache_remote = { path = "../cache-remote" }
1820
moon_codegen = { path = "../codegen" }
1921
moon_common = { path = "../common" }
2022
moon_config = { path = "../config" }
@@ -70,14 +72,23 @@ proto_core = { workspace = true }
7072
regex = { workspace = true }
7173
reqwest = { workspace = true }
7274
rustc-hash = { workspace = true }
73-
schematic = { workspace = true, features = ["config", "schema", "renderer_template"] }
75+
schematic = { workspace = true, features = [
76+
"config",
77+
"schema",
78+
"renderer_template",
79+
] }
7480
semver = { workspace = true }
7581
serde = { workspace = true }
7682
starbase = { workspace = true }
7783
starbase_archive = { workspace = true }
7884
starbase_shell = { workspace = true }
7985
starbase_styles = { workspace = true }
80-
starbase_utils = { workspace = true, features = ["editor-config", "json", "toml", "yaml"] }
86+
starbase_utils = { workspace = true, features = [
87+
"editor-config",
88+
"json",
89+
"toml",
90+
"yaml",
91+
] }
8192
thiserror = { workspace = true }
8293
tokio = { workspace = true }
8394
tracing = { workspace = true }

crates/app/src/session.rs

Lines changed: 46 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,19 @@ use async_trait::async_trait;
55
use moon_action_graph::{ActionGraphBuilder, ActionGraphBuilderOptions};
66
use moon_api::Launchpad;
77
use moon_app_context::AppContext;
8-
use moon_cache::CacheEngine;
8+
use moon_cache::{CacheContext, CacheEngine};
9+
use moon_cache_local::LocalStorage;
10+
use moon_cache_remote::{GrpcRemoteStorage, HttpRemoteStorage};
911
use moon_codegen::CodeGenerator;
1012
use moon_common::{is_docker, is_formatted_output, is_remote, is_test_env};
11-
use moon_config::{ExtensionsConfig, InheritedTasksManager, ToolchainsConfig, WorkspaceConfig};
13+
use moon_config::{
14+
ExtensionsConfig, InheritedTasksManager, RemoteApi, ToolchainsConfig, WorkspaceConfig,
15+
};
1216
use moon_config_loader::ConfigLoader;
1317
use moon_console::{Console, MoonReporter, create_console_theme};
1418
use moon_daemon::{DaemonClient, DaemonConnector};
1519
use moon_env::MoonEnvironment;
20+
use moon_env_var::GlobalEnvBag;
1621
use moon_extension_plugin::*;
1722
use moon_plugin::MoonHostData;
1823
use moon_process::ProcessRegistry;
@@ -196,10 +201,39 @@ impl MoonSession {
196201

197202
pub fn get_cache_engine(&self) -> miette::Result<Arc<CacheEngine>> {
198203
if self.cache_engine.get().is_none() {
199-
let _ = self.cache_engine.set(Arc::new(CacheEngine::new(
200-
&self.config_dir,
201-
&self.workspace_config.cache,
202-
)?));
204+
let context = CacheContext {
205+
cache_dir: self.config_dir.join("cache"),
206+
cache_config: Arc::new(self.workspace_config.cache.clone()),
207+
config_dir: self.config_dir.clone(),
208+
remote_config: Arc::new(self.workspace_config.remote.clone()),
209+
remote_debug: GlobalEnvBag::instance().should_debug_remote(),
210+
workspace_root: self.workspace_root.clone(),
211+
};
212+
213+
let mut engine = CacheEngine::new(context.clone())?;
214+
215+
engine.storage.add_local_backend(LocalStorage::new(
216+
context.clone(),
217+
&context.cache_dir,
218+
false,
219+
)?);
220+
221+
if context.remote_config.is_enabled() {
222+
match context.remote_config.api {
223+
RemoteApi::Grpc => {
224+
engine
225+
.storage
226+
.add_remote_backend(GrpcRemoteStorage::new(context.clone())?);
227+
}
228+
RemoteApi::Http => {
229+
engine
230+
.storage
231+
.add_remote_backend(HttpRemoteStorage::new(context.clone())?);
232+
}
233+
};
234+
}
235+
236+
let _ = self.cache_engine.set(Arc::new(engine));
203237
}
204238

205239
Ok(self.cache_engine.get().map(Arc::clone).unwrap())
@@ -463,6 +497,12 @@ impl AppSession for MoonSession {
463497
let _ = daemon.stop().await;
464498
}
465499

500+
// Ensure all in-flight storage tasks have finished
501+
self.get_cache_engine()?
502+
.storage
503+
.wait_for_background_tasks()
504+
.await?;
505+
466506
// Ensure all child processes have finished running
467507
ProcessRegistry::instance()
468508
.wait_for_running_to_shutdown()

crates/blob/src/blob.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,3 +51,14 @@ impl Debug for Blob {
5151
.finish()
5252
}
5353
}
54+
55+
impl TryFrom<Bytes> for Blob {
56+
type Error = miette::Report;
57+
58+
fn try_from(bytes: Bytes) -> Result<Self, Self::Error> {
59+
Ok(Blob {
60+
digest: Digest::from_bytes(&bytes)?,
61+
bytes,
62+
})
63+
}
64+
}

0 commit comments

Comments
 (0)