moka-rs / moka

A high performance concurrent caching library for Rust
Apache License 2.0
1.56k stars 69 forks source link

Feature Request: Alternative compute API that skips if other thread/async task is already computing for the key #433

Open tatsuya6502 opened 3 months ago

tatsuya6502 commented 3 months ago

Split from:

As of moka@v0.12.7, concurrent calls on Entry's and_compute_with/and_try_compute_with for the same key are serialized by the cache. If caller A and B called and_compute_with for the same key at the same time, only one of the closures f from either A or B is evaluated first. And once finish, another closure is evaluated (https://github.com/moka-rs/moka/issues/432#issuecomment-2196801694). These closures are always called, but not at the same time.

There will be some use cases that do not need/want the latter closure to be evaluated, and return immediately instead of blocking.

I have not came up with a good short name for the alternative methods yet. But they could be like the followings:

use moka::future::Cache;

let result = cache
    .entry_by_ref(&key)
    .and_try_compute_if_nobody_else(|entry| async move { 
        ... 
    }).await?;

Should I try the builder pattern?

let result = cache
    .entry_builder_by_ref(&key)
    .try_compute_with(|entry| async move {
        ...
    })
    .skip_if_already_in_progress()
    .run()
    .await?;