Skip to content

design: cross-SDK interop mode for cache key and value format #1

@27Bslash6

Description

@27Bslash6

Problem

The current auto-generated key format includes language-specific function identity:

Python: ns:users:func:myapp.services.get_user:args:{hash}:1s
Rust:   ns:users:func:myapp::services::get_user:args:{hash}:1s
Go:     ns:users:func:services.GetUser:args:{hash}:1s

These are different keys in Redis. Cross-SDK cache sharing doesn't work despite the spec claiming it does via namespace agreement. The func: segment and metadata suffix make keys inherently language-specific.

Similarly, values use the ByteStorage envelope (LZ4 + xxHash3-64) which is only implemented in the Rust crate. SDKs without cachekit-core can't read Python/Rust cache values.

Proposed Solution: Two Modes

Auto mode (default, no change)

ns:{namespace}:func:{module}.{qualname}:args:{hash}:{ic}{serializer}

Single-SDK, convenient, collision-safe. No cross-SDK compatibility needed.

Interop mode (new, opt-in)

{namespace}:{operation}:{args_hash}

Cross-SDK compatible. Requires:

  • Explicit operation name (language-neutral, e.g., "get_user")
  • Plain MessagePack values (no ByteStorage envelope)
  • Canonical argument normalization (type mapping table)
@cache(interop="get_user", namespace="users", ttl=300)
def get_user(user_id: int): ...

Canonical Type Mapping (for args hash)

Source Type MessagePack Type Notes
int int Arbitrary precision → msgpack int
float float64 IEEE 754
str str UTF-8
bool bool
null/None/nil nil
list/array array Preserve order
dict/map map Keys sorted lexicographically
set array Sorted, then encoded as array
datetime float64 UTC Unix timestamp
UUID str Lowercase hyphenated form
bytes bin Raw binary

Nested dicts: recursively sort keys at every level.

Value Format in Interop Mode

Plain MessagePack. No ByteStorage envelope, no LZ4, no xxHash3-64. Any language with a MessagePack library can read it.

Encryption still works — the AAD v0x03 format binds to the key string, which is now identical across SDKs.

Test Vectors Needed

  1. Argument normalization: given (42, "hello", {"b": 2, "a": 1}), the canonical msgpack bytes are [exact hex]
  2. Key generation: given namespace="users", operation="get_user", args=(42,), the key is users:get_user:[exact hash]
  3. Value round-trip: given {"name": "alice", "age": 30}, the plain msgpack bytes are [exact hex]

What doesn't change

  • Default behavior (auto mode) — no breaking changes
  • SaaS API — already format-agnostic, stores opaque bytes
  • Encryption protocol — AAD binds to key string, works in both modes

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions