Skip to content

Commit

Permalink
feat: Add possibility to configure key prefix (Redis, MemCached) (#2084)
Browse files Browse the repository at this point in the history
  • Loading branch information
AJIOB authored Feb 15, 2024
1 parent ffe3070 commit e445b79
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 18 deletions.
42 changes: 41 additions & 1 deletion docs/Configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,17 +57,38 @@ cache_to = "sccache-latest"
cache_from = "sccache-"

[cache.memcached]
url = "..."
url = "127.0.0.1:11211"
# Entry expiration time in seconds. Default is 86400 (24 hours)
expiration = 3600
key_prefix = "/custom/prefix/if/need"

[cache.redis]
url = "redis://user:[email protected]:6379/?db=1"
# Entry expiration time in seconds. Default is 0 (never expire)
expiration = 3600
key_prefix = "/custom/prefix/if/need"

[cache.s3]
bucket = "name"
endpoint = "s3-us-east-1.amazonaws.com"
use_ssl = true
key_prefix = "s3prefix"
server_side_encryption = false

[cache.webdav]
endpoint = "http://192.168.10.42:80/some/webdav.php"
key_prefix = "/custom/webdav/subfolder/if/need"
# Basic HTTP authentication credentials.
username = "alice"
password = "secret12"
# Mutually exclusive with username & password. Bearer token value
token = "token123"

[cache.oss]
bucket = "name"
endpoint = "oss-us-east-1.aliyuncs.com"
key_prefix = "ossprefix"
no_credentials = true
```

sccache looks for its configuration file at the path indicated by env variable `SCCACHE_CONF`.
Expand All @@ -77,6 +98,8 @@ If no such env variable is set, sccache looks at default locations as below:
- macOS: `~/Library/Application Support/Mozilla.sccache/config`
- Windows: `%APPDATA%\Mozilla\sccache\config\config`

The latest `cache.XXX` entries may be found here: https://github.com/mozilla/sccache/blob/ffe3070f77ef3301c8ff718316e4ab017ec83042/src/config.rs#L300.

## env

Whatever is set by a file based configuration, it is overruled by the env
Expand Down Expand Up @@ -147,3 +170,20 @@ The full url appears then as `redis://user:[email protected]:6379/?db=1`.
* `SCCACHE_GHA_RUNTIME_TOKEN` / `ACTIONS_RUNTIME_TOKEN` GitHub Actions access token
* `SCCACHE_GHA_CACHE_TO` cache key to write
* `SCCACHE_GHA_CACHE_FROM` comma separated list of cache keys to read from

#### webdav

* `SCCACHE_WEBDAV_ENDPOINT`
* `SCCACHE_WEBDAV_KEY_PREFIX`
* `SCCACHE_WEBDAV_USERNAME`
* `SCCACHE_WEBDAV_PASSWORD`
* `SCCACHE_WEBDAV_TOKEN`

#### OSS

* `SCCACHE_OSS_BUCKET`
* `SCCACHE_OSS_ENDPOINT`
* `SCCACHE_OSS_KEY_PREFIX`
* `ALIBABA_CLOUD_ACCESS_KEY_ID`
* `ALIBABA_CLOUD_ACCESS_KEY_SECRET`
* `SCCACHE_OSS_NO_CREDENTIALS`
11 changes: 8 additions & 3 deletions src/cache/cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -602,17 +602,22 @@ pub fn storage_from_config(
CacheType::Memcached(config::MemcachedCacheConfig {
ref url,
ref expiration,
ref key_prefix,
}) => {
debug!("Init memcached cache with url {url}");

let storage = MemcachedCache::build(url, *expiration)
let storage = MemcachedCache::build(url, key_prefix, *expiration)
.map_err(|err| anyhow!("create memcached cache failed: {err:?}"))?;
return Ok(Arc::new(storage));
}
#[cfg(feature = "redis")]
CacheType::Redis(config::RedisCacheConfig { ref url, ref ttl }) => {
CacheType::Redis(config::RedisCacheConfig {
ref url,
ref ttl,
ref key_prefix,
}) => {
debug!("Init redis cache with url {url}");
let storage = RedisCache::build(url, *ttl)
let storage = RedisCache::build(url, key_prefix, *ttl)
.map_err(|err| anyhow!("create redis cache failed: {err:?}"))?;
return Ok(Arc::new(storage));
}
Expand Down
5 changes: 3 additions & 2 deletions src/cache/memcached.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,11 @@ use crate::errors::*;
pub struct MemcachedCache;

impl MemcachedCache {
pub fn build(url: &str, expiration: u32) -> Result<Operator> {
pub fn build(url: &str, key_prefix: &str, expiration: u32) -> Result<Operator> {
let mut builder = Memcached::default();
builder.endpoint(url);
builder.default_ttl(Duration::from_secs(expiration as u64));
builder.root(key_prefix);
builder.default_ttl(Duration::from_secs(expiration.into()));

let op = Operator::new(builder)?
.layer(LoggingLayer::default())
Expand Down
3 changes: 2 additions & 1 deletion src/cache/redis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,14 @@ pub struct RedisCache;

impl RedisCache {
/// Create a new `RedisCache`.
pub fn build(url: &str, ttl: u64) -> Result<Operator> {
pub fn build(url: &str, key_prefix: &str, ttl: u64) -> Result<Operator> {
let parsed = Url::parse(url)?;

let mut builder = Redis::default();
builder.endpoint(parsed.as_str());
builder.username(parsed.username());
builder.password(parsed.password().unwrap_or_default());
builder.root(key_prefix);
if ttl != 0 {
builder.default_ttl(Duration::from_secs(ttl));
}
Expand Down
52 changes: 41 additions & 11 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -224,15 +224,24 @@ pub struct GHACacheConfig {
/// Please change this value freely if we have a better choice.
const DEFAULT_MEMCACHED_CACHE_EXPIRATION: u32 = 86400;

fn default_memcached_cache_expiration() -> u32 {
DEFAULT_MEMCACHED_CACHE_EXPIRATION
}

#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct MemcachedCacheConfig {
pub url: String,

/// the expiration time in seconds.
///
/// Default to 24 hours (86400)
/// Up to 30 days (2592000)
#[serde(default = "default_memcached_cache_expiration")]
pub expiration: u32,

#[serde(default)]
pub key_prefix: String,
}

/// redis has no default TTL - all caches live forever
Expand All @@ -245,17 +254,22 @@ const DEFAULT_REDIS_CACHE_TTL: u64 = 0;
#[serde(deny_unknown_fields)]
pub struct RedisCacheConfig {
pub url: String,
/// the ttl time in seconds.

/// the ttl (expiration) time in seconds.
///
/// Default to infinity (0)
#[serde(default)]
#[serde(default, alias = "expiration")]
pub ttl: u64,

#[serde(default)]
pub key_prefix: String,
}

#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct WebdavCacheConfig {
pub endpoint: String,
#[serde(default)]
pub key_prefix: String,
pub username: Option<String>,
pub password: Option<String>,
Expand All @@ -267,6 +281,7 @@ pub struct WebdavCacheConfig {
pub struct S3CacheConfig {
pub bucket: String,
pub region: Option<String>,
#[serde(default)]
pub key_prefix: String,
pub no_credentials: bool,
pub endpoint: Option<String>,
Expand All @@ -278,6 +293,7 @@ pub struct S3CacheConfig {
#[serde(deny_unknown_fields)]
pub struct OSSCacheConfig {
pub bucket: String,
#[serde(default)]
pub key_prefix: String,
pub endpoint: Option<String>,
pub no_credentials: bool,
Expand Down Expand Up @@ -610,9 +626,11 @@ fn config_from_env() -> Result<EnvConfig> {
.map_err(|err| anyhow!("SCCACHE_REDIS_TTL value is invalid: {err:?}"))?,
Err(_) => DEFAULT_REDIS_CACHE_TTL,
};
let redis = env::var("SCCACHE_REDIS")
.ok()
.map(|url| RedisCacheConfig { url, ttl });
let redis = env::var("SCCACHE_REDIS").ok().map(|url| RedisCacheConfig {
url,
ttl,
key_prefix: String::new(),
});

// ======= memcached =======
let expiration = match env::var("SCCACHE_MEMCACHED_EXPIRATION").ok() {
Expand All @@ -624,7 +642,11 @@ fn config_from_env() -> Result<EnvConfig> {

let memcached = env::var("SCCACHE_MEMCACHED")
.ok()
.map(|url| MemcachedCacheConfig { url, expiration });
.map(|url| MemcachedCacheConfig {
url,
expiration,
key_prefix: String::new(),
});

// ======= GCP/GCS =======
if (env::var("SCCACHE_GCS_CREDENTIALS_URL").is_ok()
Expand Down Expand Up @@ -1180,6 +1202,7 @@ fn config_overrides() {
redis: Some(RedisCacheConfig {
url: "myotherredisurl".to_owned(),
ttl: 24 * 3600,
key_prefix: String::new(),
}),
..Default::default()
},
Expand All @@ -1196,10 +1219,12 @@ fn config_overrides() {
memcached: Some(MemcachedCacheConfig {
url: "memurl".to_owned(),
expiration: 24 * 3600,
key_prefix: String::new(),
}),
redis: Some(RedisCacheConfig {
url: "myredisurl".to_owned(),
ttl: 24 * 3600,
key_prefix: String::new(),
}),
..Default::default()
},
Expand All @@ -1213,6 +1238,7 @@ fn config_overrides() {
cache: Some(CacheType::Redis(RedisCacheConfig {
url: "myotherredisurl".to_owned(),
ttl: 24 * 3600,
key_prefix: String::new(),
}),),
fallback_cache: DiskCacheConfig {
dir: "/env-cache".into(),
Expand Down Expand Up @@ -1373,12 +1399,14 @@ enabled = true
version = "sccache"
[cache.memcached]
url = "..."
expiration = 86400
url = "127.0.0.1:11211"
expiration = 90000
key_prefix = "/custom/prefix/if/need"
[cache.redis]
url = "redis://user:[email protected]:6379/1"
ttl = 86400
expiration = 86400
key_prefix = "/my/redis/cache"
[cache.s3]
bucket = "name"
Expand Down Expand Up @@ -1430,10 +1458,12 @@ no_credentials = true
redis: Some(RedisCacheConfig {
url: "redis://user:[email protected]:6379/1".to_owned(),
ttl: 24 * 3600,
key_prefix: "/my/redis/cache".into(),
}),
memcached: Some(MemcachedCacheConfig {
url: "...".to_owned(),
expiration: 24 * 3600
url: "127.0.0.1:11211".to_owned(),
expiration: 25 * 3600,
key_prefix: "/custom/prefix/if/need".into(),
}),
s3: Some(S3CacheConfig {
bucket: "name".to_owned(),
Expand Down

0 comments on commit e445b79

Please sign in to comment.