Skip to content

Commit

Permalink
Support configuring the TTL, scope, and cache dir via environment
Browse files Browse the repository at this point in the history
variables in addition to flags.

I opted not to add an environment variable for --stale at this time
because I'm not convinced how useful it would be. It's easy enough to
add in the future, though I would prefer a more descriptive name than
BKT_STALE if it's added.

BKT_CACHE_DIR serves a very similar purpose to BKT_TMPDIR which was
added in 77c5d91. I decided to use a separate variable to more directly
mirror the --cache-dir flag. Notably, BKT_TMPDIR is respected by the bkt
library whereas BKT_CACHE_DIR is only evaluated at parse time in the
binary. In the future these variables might also have slightly different
behavior, e.g. bkt might create a different directory heirarchy if
BKT_TMPDIR is set instead of BKT_CACHE_DIR.

Credit to @JulienPalard for the idea in dimo414#15.
  • Loading branch information
dimo414 committed Jul 8, 2022
1 parent c862ff5 commit aed4c81
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 12 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ debug = ['serde_json']
[dependencies]
anyhow = "1.0"
bincode = "1.3.1"
clap = { version = "3.0", default_features = false, features = ["std", "derive"] }
clap = { version = "3.0", default_features = false, features = ["std", "derive", "env"] }
humantime = "2.1.0"
rand = "0.8"
serde = { version = "1.0", features = ["derive"] }
Expand Down
36 changes: 28 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,17 +64,19 @@ Two flags, `--ttl` and `--stale`, configure how long cached data is preserved.
By default `bkt` uses a TTL (Time to Live) of 60 seconds, meaning cached
data older than sixty seconds will be discarded and the backing command re-run.
Passing a different value, such as `--ttl=1d`, will change how long the cached
data is considered valid.
data is considered valid. The default TTL can be overriden by defining a
`BKT_TTL` environment variable.

When the data expires `bkt` has to re-execute the command synchronously, which
can introduce unexpected slowness. To avoid this, pass `--stale` with a shorter
duration than the TTL. This causes `bkt` to refresh the cache in the background
when the cached data is older than the stale threshold while still returning
the old data promptly.

Both flags accept duration strings such as `10s` or `1hour 30min`. The exact
syntax is defined in the
[humantime](https://docs.rs/humantime/2.1.0/humantime/fn.parse_duration.html) library.
Both flags (and `BKT_TTL`) accept duration strings such as `10s` or
`1hour 30min`. The exact syntax is defined in the
[humantime](https://docs.rs/humantime/2.1.0/humantime/fn.parse_duration.html)
library.

### Execution Environment

Expand Down Expand Up @@ -144,6 +146,17 @@ $ bkt --scope=foo -- date +%s.%N
1631992418.010562000
```

Alternatively, define a `BKT_SCOPE` environment variable to configure a
consistent scope across invocations. This can be useful within a script to
ensure all commands share a scope.

```shell
#!/bin/bash

# Set a unique scope for this script invocation using the PID and current time
export BKT_SCOPE="my_script_$$_$(date -Ins)"
```

### Discarding Failed Invocations

By default, all invocations are cached regardless of their output or exit code.
Expand All @@ -161,9 +174,15 @@ flag and instead make the client robust to occasional failures.
### Changing the Cache Directory

By default, cached data is stored under `/tmp` or a similar temporary directory;
this can be customized via the `--cache-dir` flag, or by setting the
`BKT_TMPDIR` environment variable. If both `BKT_TMPDIR` and `--cache-dir` are
used the flag `--cache-dir` will take priority.
this can be customized via the `--cache-dir` flag or by defining a
`BKT_CACHE_DIR` environment variable.

If a `BKT_TMPDIR` environment variable is defined it wil be used instead of the
system's temporary directory. Although `BKT_TMPDIR` and `BKT_CACHE_DIR` have
similar effects `BKT_TMPDIR` is intended to be used to configure the global
cache location (e.g. by declaring it in your `.bashrc` or similar), while
`--cache-dir`/`BKT_CACHE_DIR` should be used to customize the cache location
for a given set of invocations that shouldn't use the default cache directory.

Note that the choice of directory can affect `bkt`'s performance: if the cache
is stored under a [`tmpfs`](https://en.wikipedia.org/wiki/Tmpfs) or solid-state
Expand All @@ -180,7 +199,8 @@ you trust such as `~/.bkt`, but note that your home directory may be slower than
the temporary directory selected by default.

In general, if you are not the only user of your system it's wise to configure
your `TMPDIR` to a location only you can access.
your `TMPDIR` to a location only you can access. If that is not possible use
`BKT_TMPDIR` to configure a custom temporary directory specifically for `bkt`.

## Patterns and Tips

Expand Down
6 changes: 3 additions & 3 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ struct Cli {
command: Vec<OsString>,

/// Duration the cached result will be valid for
#[clap(long, default_value = "60s", visible_alias = "time-to-live")]
#[clap(long, default_value = "60s", visible_alias = "time-to-live", env = "BKT_TTL")]
ttl: humantime::Duration,

/// Duration after which the result will be asynchronously refreshed
Expand Down Expand Up @@ -142,14 +142,14 @@ struct Cli {

/// If set, all cached data will be scoped to this value,
/// preventing collisions with commands cached with different scopes
#[clap(long)]
#[clap(long, env = "BKT_SCOPE")]
scope: Option<String>,

/// The directory under which to persist cached invocations;
/// defaults to the system's temp directory.
/// Setting this to a directory backed by RAM or an SSD, such as a tmpfs partition,
/// will significantly reduce caching overhead.
#[clap(long)]
#[clap(long, env = "BKT_CACHE_DIR")]
cache_dir: Option<PathBuf>,
}

Expand Down
12 changes: 12 additions & 0 deletions tests/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,12 +114,19 @@ mod cli {
let first_result = succeed(bkt(dir.path("cache")).args(args));
assert_eq!(first_result, "1");

// Slightly stale is still cached
make_dir_stale(dir.path("cache"), Duration::from_secs(10)).unwrap();
let subsequent_result = succeed(bkt(dir.path("cache")).args(args));
assert_eq!(first_result, subsequent_result);

make_dir_stale(dir.path("cache"), Duration::from_secs(120)).unwrap();
let after_stale_result = succeed(bkt(dir.path("cache")).args(args));
assert_eq!(after_stale_result, "2");

// Respects BKT_TTL env var (other tests cover --ttl)
make_dir_stale(dir.path("cache"), Duration::from_secs(10)).unwrap();
let env_result = succeed(bkt(dir.path("cache")).env("BKT_TTL", "5s").args(args));
assert_eq!(env_result, "3");
}

#[test]
Expand Down Expand Up @@ -244,6 +251,9 @@ mod cli {

let diff_cache = succeed(bkt(dir.path("cache")).arg(format!("--cache-dir={}", dir.path("new-cache").display())).args(args));
assert_eq!(diff_cache, "2");

let env_cache = succeed(bkt(dir.path("cache")).env("BKT_CACHE_DIR", dir.path("env-cache").as_os_str()).args(args));
assert_eq!(env_cache, "3");
}

// https://github.com/dimo414/bkt/issues/9
Expand Down Expand Up @@ -275,6 +285,8 @@ mod cli {
assert_eq!(diff_scope, "2");
assert_eq!(diff_scope, succeed(bkt(dir.path("cache"))
.arg("--scope=foo").args(args)));
assert_eq!(diff_scope, succeed(bkt(dir.path("cache"))
.env("BKT_SCOPE", "foo").args(args)));
}

#[test]
Expand Down

0 comments on commit aed4c81

Please sign in to comment.