version-0.1.0 — Initial Beta Release
Released: 2026-07-04
Library version: 0.1.0 · Protocol version: 1.0
Python: ≥ 3.10 (tested through 3.13) · Redis: ≥ 5.0
License: MIT
First public Beta of gpdatacached — a Redis-backed cross-process data
sharing and caching library. Any process that can reach the same Redis
instance can share live, mutable, typed data structures with reference
semantics, per-object lifecycle control, reference counting with
cascade-delete, a background GC, and opt-in distributed locking.
Beta status: the API surface is stabilizing but may still change before 1.0.
Wire/Redis layout (GPDC_PROTOCOL_VERSION = 1.0) is intended to be stable
within the 1.x protocol family.
✨ Highlights
Core
- Dict-like API over Redis —
ns["x"] = value; ns["x"]with native Python
type round-tripping (scalars return native values, containers return live
objects). - Domain → Namespace → Object model (
GPDCDomain/GPDCNamespace/
GPDCDataObject), each backed by a pooled Redis client. - Live containers —
ns["tags"].append("x")mutates Redis directly; no
read-modify-write of the whole structure. - Reference sharing — bind the same container under multiple names within
a namespace; underlying data is stored once.
Type system (extensible registry + codec architecture)
- Built-in scalars:
int,float,str,bool,datetime/date/time,
tuple(composite scalar),None. - Built-in containers:
list,dict,set. - Custom types register via
GPDCTypeRegistry.register(...)with a
python_type ↔ gpdc_type ↔ object_class ↔ codec_classtriple.
Lifecycle & ownership
- Three cache modes:
permanent(default),ttl(fixed expiry),
sliding(TTL refreshed on every mutation). - Cascade propagation of lifecycle policy to owned subtrees.
- Reference counting with cascade-delete of orphaned anonymous objects;
canonical objects referenced by aliases cannot be deleted until aliases are
removed (CanonicalObjectReferencedError). - Anonymous objects (
~anon:<uuid>) auto-created for nested containers.
Opt-in distributed locking
obj.lock()/obj.try_lock()— locks the canonical name so references
and owners resolve to the same lock; never called automatically by
mutating methods.- Algorithm:
SET NX EXfast-path →BLPOPwake-up queue, capped at
min(remaining, ttl)so a crashed holder is recovered within ~ttl. - Atomic Lua release (verify token → DEL → RPUSH wake).
- Write-or-verify lock config;
reset_domain_config(...)to change on an
existing domain.
Garbage collection
- Background daemon thread per domain (opt-in via
gc_enabled=True) or manual
domain.run_gc(...). SCAN-based cleanup; processes each canonical inside its own lock and
skips on contention — never deadlocks against a writer holding
obj.lock().- GC is off by default.
Extensions
- Pydantic (core dependency) —
BaseModelas atomic JSON scalar or as a
container with field-level access and nested container fields. - Pandas (
pip install "gpdatacached[pandas]") — cacheablepd.Series/
pd.DataFramewith fullMultiIndex(rows + columns) support, selective
one-shot reads (.iloc,.loc,df[col]), and append-focused mutation
(extend, column__setitem__/__delitem__). Cost-bar guidance in the
Performance Guide.
Ecosystem
- MkDocs Material documentation site with i18n (English + Simplified
Chinese), deployed via GitHub Pages. - PyPI packaging ready with trusted-publishing CI.
🔧 Technical notes
- All Redis keys go through builders in
keys.py(prefixedgpdc:); never
hand-rolled. - Containers' mutating methods always call
_touch()and release old element
refs; wholesale replacement of container.valueis rejected. encode_sessionprovides cycle detection and safe aliasing for multi-element
encodes (withid()-reuse safeguards documented inpandas_support.py).