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

WIP: Add option to skip RW mode check #2133

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
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
8 changes: 8 additions & 0 deletions docs/Configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ cache_dir = "/home/user/.cache/sccache-dist-client"
type = "token"
token = "secrettoken"

[cache]
# If specified, skip the startup check for whether the backend is read-only/writeable;
# assume it has this mode instead.
# If unspecified, the server will check the mode at startup.
assume_rw_mode = "READ_WRITE"

#[cache.azure]
# does not work as it appears
Expand Down Expand Up @@ -136,6 +141,9 @@ configuration variables

### cache configs

* `SCCACHE_ASSUME_RW_MODE` to skip checking whether the cache is correctly configured.
Instead, assume it is `READ_ONLY` or `READ_WRITE`- whichever this environment variable specifies.

#### disk (local)

* `SCCACHE_DIR` local on disk artifact cache directory
Expand Down
42 changes: 39 additions & 3 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,10 @@ pub enum CacheType {
#[derive(Debug, Default, Serialize, Deserialize, PartialEq, Eq)]
#[serde(deny_unknown_fields)]
pub struct CacheConfigs {
/// If set, assume that the configure cache has the given mode
/// (without checking at server startup).
pub assume_rw_mode: Option<CacheModeConfig>,

pub azure: Option<AzureCacheConfig>,
pub disk: Option<DiskCacheConfig>,
pub gcs: Option<GCSCacheConfig>,
Expand All @@ -358,8 +362,9 @@ pub struct CacheConfigs {
impl CacheConfigs {
/// Return cache type in an arbitrary but
/// consistent ordering
fn into_fallback(self) -> (Option<CacheType>, DiskCacheConfig) {
fn into_fallback(self) -> (Option<CacheModeConfig>, Option<CacheType>, DiskCacheConfig) {
let CacheConfigs {
assume_rw_mode,
azure,
disk,
gcs,
Expand All @@ -383,12 +388,13 @@ impl CacheConfigs {

let fallback = disk.unwrap_or_default();

(cache_type, fallback)
(assume_rw_mode, cache_type, fallback)
}

/// Override self with any existing fields from other
fn merge(&mut self, other: Self) {
let CacheConfigs {
assume_rw_mode,
azure,
disk,
gcs,
Expand All @@ -400,6 +406,10 @@ impl CacheConfigs {
oss,
} = other;

if assume_rw_mode.is_some() {
self.assume_rw_mode = assume_rw_mode;
}

if azure.is_some() {
self.azure = azure
}
Expand Down Expand Up @@ -904,7 +914,21 @@ fn config_from_env() -> Result<EnvConfig> {
None
};

let assume_rw_mode = match env::var("SCCACHE_ASSUME_RW_MODE")
.as_ref()
.map(String::as_str)
{
Ok("READ_ONLY") => Some(CacheModeConfig::ReadOnly),
Ok("READ_WRITE") => Some(CacheModeConfig::ReadWrite),
Ok(_) => {
warn!("Invalid SCCACHE_ASSUME_RW_MODE; ignoring value. The server may check the mode explicitly.");
None
}
_ => None,
};

let cache = CacheConfigs {
assume_rw_mode,
azure,
disk,
gcs,
Expand Down Expand Up @@ -948,6 +972,10 @@ pub struct Config {
pub fallback_cache: DiskCacheConfig,
pub dist: DistConfig,
pub server_startup_timeout: Option<std::time::Duration>,

/// If set, skip the check on `cache`'s RW/RO mode on server startup.
/// Assume that it has this mode instead.
pub assume_rw_mode: Option<CacheModeConfig>,
}

impl Config {
Expand Down Expand Up @@ -978,12 +1006,13 @@ impl Config {
let EnvConfig { cache } = env_conf;
conf_caches.merge(cache);

let (caches, fallback_cache) = conf_caches.into_fallback();
let (assume_rw_mode, caches, fallback_cache) = conf_caches.into_fallback();
Self {
cache: caches,
fallback_cache,
dist,
server_startup_timeout,
assume_rw_mode,
}
}
}
Expand Down Expand Up @@ -1234,6 +1263,7 @@ fn test_parse_size() {
fn config_overrides() {
let env_conf = EnvConfig {
cache: CacheConfigs {
assume_rw_mode: Some(CacheModeConfig::ReadOnly),
azure: Some(AzureCacheConfig {
connection_string: String::new(),
container: String::new(),
Expand All @@ -1260,6 +1290,7 @@ fn config_overrides() {

let file_conf = FileConfig {
cache: CacheConfigs {
assume_rw_mode: Some(CacheModeConfig::ReadWrite),
disk: Some(DiskCacheConfig {
dir: "/file-cache".into(),
size: 15,
Expand Down Expand Up @@ -1287,6 +1318,7 @@ fn config_overrides() {
assert_eq!(
Config::from_env_and_file_configs(env_conf, file_conf),
Config {
assume_rw_mode: Some(CacheModeConfig::ReadOnly),
cache: Some(CacheType::Redis(RedisCacheConfig {
endpoint: Some("myotherredisurl".to_owned()),
ttl: 24 * 3600,
Expand Down Expand Up @@ -1421,6 +1453,9 @@ fn full_toml_parse() {
const CONFIG_STR: &str = r#"
server_startup_timeout_ms = 10000

[cache]
assume_rw_mode = "READ_ONLY"

[dist]
# where to find the scheduler
scheduler_url = "http://1.2.3.4:10600"
Expand Down Expand Up @@ -1502,6 +1537,7 @@ no_credentials = true
file_config,
FileConfig {
cache: CacheConfigs {
assume_rw_mode: Some(CacheModeConfig::ReadOnly),
azure: None, // TODO not sure how to represent a unit struct in TOML Some(AzureCacheConfig),
disk: Some(DiskCacheConfig {
dir: PathBuf::from("/tmp/.cache/sccache"),
Expand Down
41 changes: 25 additions & 16 deletions src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -443,23 +443,32 @@ pub fn start_server(config: &Config, port: u16) -> Result<()> {
}
};

let cache_mode = runtime.block_on(async {
match raw_storage.check().await {
Ok(mode) => Ok(mode),
Err(err) => {
error!("storage check failed for: {err:?}");

notify_server_startup(
&notify,
ServerStartup::Err {
reason: err.to_string(),
},
)?;

Err(err)
let cache_mode = if let Some(rw_mode) = config.assume_rw_mode {
// We've been provided with a RW mode to assume this cache has.
// Use it.
Ok(rw_mode.into())
} else {
// Before starting to use this cache (raw_storage), we need to check whether it's ReadOnly or ReadWrite-
// or if it's altogether unreachable.
runtime.block_on(async {
match raw_storage.check().await {
Ok(mode) => Ok(mode),
Err(err) => {
error!("storage check failed for: {err:?}");

notify_server_startup(
&notify,
ServerStartup::Err {
reason: err.to_string(),
},
)?;

Err(err)
}
}
}
})?;
})
}?;

info!("server has setup with {cache_mode:?}");

let storage = match cache_mode {
Expand Down
1 change: 1 addition & 0 deletions tests/harness/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ pub fn sccache_client_cfg(
};
sccache::config::FileConfig {
cache: sccache::config::CacheConfigs {
assume_rw_mode: None,
azure: None,
disk: Some(disk_cache),
gcs: None,
Expand Down