Skip to content

invalidate_cache() no-op for async functions in L1-only mode #110

@27Bslash6

Description

@27Bslash6

Problem

invalidate_cache() called with no arguments on an async-decorated function does not clear the L1 cache in backend=None (L1-only) mode.

Reproduction

from cachekit import cache
import asyncio

call_count = 0

@cache(backend=None, ttl=300)
async def fn(x):
    global call_count
    call_count += 1
    return x * 2

async def test():
    global call_count

    await fn(5)
    print(f"After call 1: computed={call_count}")  # 1

    await fn(5)
    print(f"After call 2: computed={call_count}")  # 1 (cached)

    # Per-key invalidation works:
    await fn.invalidate_cache(5)
    await fn(5)
    print(f"After invalidate(5), call 3: computed={call_count}")  # 2 (recomputed) OK

    # No-arg bulk invalidation does NOT work:
    await fn.invalidate_cache()
    await fn(5)
    print(f"After invalidate(), call 4: computed={call_count}")  # 2 (still cached!) BUG

asyncio.run(test())

Expected

Call 4 should recompute (computed=3) because invalidate_cache() with no args should clear ALL cached entries for the function.

Actual

Call 4 returns the cached value (computed=2). The no-arg bulk invalidation is a no-op.

Analysis

The no-arg path in the wrapper checks _func_has_params and iterates _cached_keys, but the L1-only mode code path may not be populating _cached_keys correctly, so the snapshot is empty and no entries are invalidated.

Additional issue

cache_clear() raises TypeError for async functions:

TypeError: cache_clear() cannot clear cache for async functions. Use 'await fn.ainvalidate_cache()' instead.

But ainvalidate_cache() (which invalidate_cache aliases to for async functions) doesn't work either, as shown above.

Environment

  • cachekit 0.4.0
  • Python 3.13
  • @cache(backend=None) (L1-only mode)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions