Skip to content

Commit

Permalink
Merge pull request #186 from Raz-Hemo/support-clone-types-and-sync-wr…
Browse files Browse the repository at this point in the history
…ites-result-fallback

Support clone types and sync writes result fallback
  • Loading branch information
jaemk authored Apr 7, 2024
2 parents 4c4b6be + eef8b69 commit 09c9111
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 6 deletions.
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,22 @@ fn keyed(a: String) -> Option<usize> {

----

```compile_fail
use cached::proc_macro::cached;
/// Cannot use sync_writes and result_fallback together
#[cached(
result = true,
time = 1,
sync_writes = true,
result_fallback = true
)]
fn doesnt_compile() -> Result<String, ()> {
Ok("a".to_string())
}
```
----

```rust,no_run,ignore
use cached::proc_macro::io_cached;
use cached::AsyncRedisCache;
Expand Down
6 changes: 5 additions & 1 deletion cached_proc_macro/src/cached.rs
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,10 @@ pub fn cached(args: TokenStream, input: TokenStream) -> TokenStream {
_ => panic!("the result and option attributes are mutually exclusive"),
};

if args.result_fallback && args.sync_writes {
panic!("the result_fallback and sync_writes attributes are mutually exclusive");
}

let set_cache_and_return = quote! {
#set_cache_block
result
Expand Down Expand Up @@ -256,7 +260,7 @@ pub fn cached(args: TokenStream, input: TokenStream) -> TokenStream {
let old_val = {
#lock
let (result, has_expired) = cache.cache_get_expired(&key);
if let (Some(result), false) = (result, has_expired) {
if let (Some(result), false) = (&result, has_expired) {
#return_cache_block
}
result
Expand Down
16 changes: 16 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,22 @@ fn keyed(a: String) -> Option<usize> {
----
```compile_fail
use cached::proc_macro::cached;
/// Cannot use sync_writes and result_fallback together
#[cached(
result = true,
time = 1,
sync_writes = true,
result_fallback = true
)]
fn doesnt_compile() -> Result<String, ()> {
Ok("a".to_string())
}
```
----
```rust,no_run,ignore
use cached::proc_macro::io_cached;
use cached::AsyncRedisCache;
Expand Down
13 changes: 8 additions & 5 deletions tests/cached.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1572,7 +1572,7 @@ fn test_expiring_value_unexpired_article_returned_with_hit() {
}

#[cached::proc_macro::cached(result = true, time = 1, result_fallback = true)]
fn always_failing() -> Result<i64, ()> {
fn always_failing() -> Result<String, ()> {
Err(())
}

Expand All @@ -1586,8 +1586,11 @@ fn test_result_fallback() {
}

// Pretend it succeeded once
ALWAYS_FAILING.lock().unwrap().cache_set((), 1);
assert_eq!(always_failing(), Ok(1));
ALWAYS_FAILING
.lock()
.unwrap()
.cache_set((), "abc".to_string());
assert_eq!(always_failing(), Ok("abc".to_string()));
{
let cache = ALWAYS_FAILING.lock().unwrap();
assert_eq!(cache.cache_hits(), Some(1));
Expand All @@ -1597,14 +1600,14 @@ fn test_result_fallback() {
std::thread::sleep(std::time::Duration::from_millis(2000));

// Even though the cache should've expired, the `result_fallback` flag means it refreshes the cache with the last valid result
assert_eq!(always_failing(), Ok(1));
assert_eq!(always_failing(), Ok("abc".to_string()));
{
let cache = ALWAYS_FAILING.lock().unwrap();
assert_eq!(cache.cache_hits(), Some(1));
assert_eq!(cache.cache_misses(), Some(2));
}

assert_eq!(always_failing(), Ok(1));
assert_eq!(always_failing(), Ok("abc".to_string()));
{
let cache = ALWAYS_FAILING.lock().unwrap();
assert_eq!(cache.cache_hits(), Some(2));
Expand Down

0 comments on commit 09c9111

Please sign in to comment.