Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Cacheable Functions

Use cacheable function helpers when ordinary async work needs the same cache boundary with less boilerplate.

The macros are intentionally explicit. They do not discover a global cache, generate hidden keys from every function argument, or hide the loader. They build CacheOptions and call the same runtime methods you could call manually.

Loader Macro

cacheable_loader! is the compact form for fallible async loaders.

    let profile_id = 42_u64;
    let profile = cacheable_loader!(
        cache = cache,
        key = "profile:42",
        tags = ["profiles", "profile:42"],
        ttl_secs = 60,
        load = move || async move {
            Ok::<_, LoadError>(Profile {
                id: profile_id,
                name: "Ada".to_owned(),
            })
        },
    )
    .await?;

    assert_eq!(profile.id, 42);

Use this when you already have a cache instance and want the call site to show key, tags, TTL, and loader in one expression.

Infallible Loader

Use cacheable_infallible! when the loader cannot fail and Ok::<_, Error>(value) would only add ceremony.

    let total = cacheable_infallible!(
        cache = cache,
        key = "profiles:count",
        tags = ["profiles"],
        ttl_secs = 60,
        load = || async { 1_u64 },
    )
    .await?;

    assert_eq!(total, 1);

The cache operation can still fail because serialization, storage, or runtime boundaries can fail. The macro only removes the loader error wrapper.

Attribute Macro

Use #[cacheable] when the cached operation is naturally an async function.

#[cacheable(
    cache = cache,
    key_segments = ["profile", profile_id],
    tag_segments = [["profile", profile_id], ["profiles"]],
    ttl_secs = 60
)]
async fn load_profile(cache: &HydraCache, profile_id: u64) -> Result<Profile, LoadError> {
    Ok(Profile {
        id: profile_id,
        name: "Ada".to_owned(),
    })
}

The cache remains an explicit function argument. The generated wrapper returns hydracache::CacheResult<T> because cache errors can occur outside the loader.

Choosing A Form

Use the explicit local cache API first when designing a new cached operation. Move to a macro when the key, tags, TTL, and loader boundary are already obvious.

Prefer:

  • cacheable_loader! for one-off fallible loaders;
  • cacheable_infallible! for one-off loaders that cannot fail;
  • #[cacheable] for reusable async functions with stable key/tag metadata.