Code Interview 1 - Redis Cache
import asyncio import aioredis import pickle
# Async cache decorator using Redis
redis = aioredis.from_url("redis://localhost")
def cache(ttl=60):
def deco(func):
async def wrapper(*args, **kwargs): key = func.name + ":" + str(args) data = redis.get(key)
if data:
return pickle.loads(data)
result = await func(*args, **kwargs)
redis.set(key, pickle.dumps(result), ex=ttl)
return result
return wrapper
return deco
@cache(ttl=120)
async def get_user_profile(user_id):
# Simulate a DB call
await asyncio.sleep(1)
return {"id": user_id, "name": "User" + user_id)
My Answer was…
I think you are trying to do caching, using Redis. Without directly accessing database, you are trying to get the user profile data.
It’s awaited.
I think you need to use try-except grammar so that you can do stable exception handling. More than that, I haven’t actually coded by myself so I don’t know deeply.
Gemini’s Feedback
The Critical Error: Missing await
Looking at the code, there is a critical issue with the asynchronous flow. The redis.get(key) call is missing the await keyword. Since it’s an I/O-bound task, without await, the variable data will hold a coroutine object instead of the actual data. This will cause the application to crash when it reaches the pickle.loads() function.
Coroutines:
https://gomdoricake.hashnode.dev/coroutines
Pickle Security Risk
First, using pickle for serialization can be a security risk. It’s vulnerable to Remote Code Execution (RCE) attacks if the data is tampered with. I would recommend using JSON instead, which is much safer and more standard.
Resource Management
Second, the connection management is missing. In a production environment, we should ensure the Redis connection is properly closed or managed using a connection pool to prevent resource leaks.
Cache Key Design
Third, the cache key design could be improved. Right now, it’s just the function name and arguments, which might cause key collisions. I would add a unique namespace to ensure the keys are distinct across different functions.
Cache Stampede
Finally, this code might suffer from a ‘Cache Stampede’ if thousands of requests hit an empty cache simultaneously. To prevent overwhelming the database, I would implement a locking mechanism or a ‘single-flight’ strategy.
My Work Process
“When I review code, I follow a 3-step checklist:
Purpose: What is the business goal? (e.g., Caching to reduce DB load)
I/O Identification: Which parts are talking to the network or database?
Async Integrity: Are all I/O operations properly awaited? Following this process helps me catch critical bugs early on.