Skip to content

五、返回值处理 ​

5.1 返回值结构 ​

python
# redis-py 库(decode_responses=True)
result = redis_client.brpop("task:queue", timeout=5)

# 有元素
print(result)
# ("task:queue", "6")
#  result[0] = 队列名(字符串)
#  result[1] = 元素值(字符串)

# 超时无元素
print(result)
# None

5.2 本项目的处理 ​

python
result = redis_client.brpop("task:queue", timeout=5)
if result:
    _, task_id = result       # 解构:忽略队列名,取元素值
    task_id = int(task_id)    # Redis 存的是字符串,转回 int
    run_task(task_id)

为什么需要 int(task_id):

python
# API 端存入时是 int
redis_client.lpush("task:queue", task.id)  # task.id = 6

# Redis 内部统一转成字符串存储
# BRPOP 取出时是 "6"(字符串)

# Worker 需要转回 int 才能查数据库
task = db.get(Task, int(task_id))  # db.get 需要 int 主键

int(x) 参数说明 ​

参数类型必填说明
xstr 或 float 或 int是要转换的值。字符串必须是纯数字,否则抛 ValueError

返回值:int

常见转换:

python
int("6")      # → 6
int("101")     # → 101
int(b"6")      # → 6(bytes 自动解码为 str 再转)
int("6.0")     # → ValueError!不能直接转浮点字符串
int(6.0)       # → 6(float 截断为 int)

decode_responses 对 int() 的影响:

python
# decode_responses=False
_, task_id = redis_client.brpop("task:queue", timeout=5)
# task_id = b"6"
int(task_id)   # → 6(bytes 也可以直接 int())

# decode_responses=True
_, task_id = redis_client.brpop("task:queue", timeout=5)
# task_id = "6"
int(task_id)   # → 6

不转换的后果:

python
# 如果忘记 int() 转换
task_id = "6"  # 字符串
task = db.get(Task, task_id)
# SQLAlchemy 报错:Integer 主键不接受字符串类型

5.3 多队列时的返回值 ​

python
result = redis_client.brpop(
    ["task:queue:vip", "task:queue:normal"],
    timeout=5
)

# VIP 队列命中
# ("task:queue:vip", "6")

# 普通队列命中
# ("task:queue:normal", "42")

# 超时
# None

通过 result[0] 可以知道任务来自哪个队列,用于日志或优先级统计:

python
if result:
    queue_name, task_id = result
    if queue_name == "task:queue:vip":
        logger.info("VIP 任务优先处理: %s", task_id)
    run_task(int(task_id))