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
    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