Skip to content
Memcached

Padrões: Read-Through, Write-Behind & Session Cache

Aplicar Memcached a problemas comuns de cache de aplicação.

#pattern#read-through#session#lock#ratelimit

Code

memcached
# --- Read-through cache (cache-aside) ---
def get_user(user_id):
    key = f"user:{user_id}"
    val = mc.get(key)
    if val is None:                    # cache miss
        val = db.query("SELECT ...", user_id)
        mc.set(key, json.dumps(val), expire=300)  # 5 min
    return json.loads(val)

# --- Write-through: update cache when DB changes ---
def update_user(user_id, data):
    db.update("users", user_id, data)
    mc.set(f"user:{user_id}", json.dumps(data), expire=300)
    # OR invalidate: mc.delete(f"user:{user_id}")

# --- Session storage (with gat to extend on access) ---
def session_read(sid):
    return mc.gat(sid, 1800)   # read + extend ttl to 30min

def session_write(sid, data):
    mc.set(sid, data, expire=1800)

# --- Lock with add (atomic) ---
def with_lock(key, ttl, fn):
    token = uuid4().hex
    if mc.add(f"lock:{key}", token, expire=ttl):
        try:
            return fn()
        finally:
            # release only if we still own the lock
            cur, cas = mc.gets(f"lock:{key}")
            if cur == token:
                mc.cas(f"lock:{key}", b"", cas, expire=1)
    else:
        raise LockedError()

# --- Counter (rate limit) ---
def rate_limit(user_id, limit=100, window=60):
    key = f"rl:{user_id}"
    n = mc.incr(key, 1)
    if n == 1:
        mc.set(key, 1, expire=window)   # set ttl on first hit
    return n <= limit