我注意到当并行运行的请求修改 Flask 时session
,只记录了一些键。Flask 的默认 cookie 会话和使用 Redis 后端的 Flask-Session 都会发生这种情况。该项目并不新鲜,但只有在同一会话同时发生许多请求时,这才变得引人注目。
import time
from flask import Flask, session
from flask_session import Session
app = Flask(__name__)
app.secret_key = "example"
app.config["SESSION_TYPE"] = "redis"
Session(app)
@app.route("/set/<value>")
def set_value(value):
"""Simulate long running task."""
time.sleep(1)
session[value] = "done"
return "ok\n"
@app.route("/keys")
def keys():
return str(session.keys()) + "\n"
以下 shell 脚本演示了该问题。请注意,所有请求都已完成,但最终清单中仅存在一个键,并且在测试运行之间有所不同。
#!/bin/bash
# set session
curl -c 'cookie' http://localhost:5007/keys
# run parallel
curl -b 'cookie' http://localhost:5007/set/key1 && echo "done1" &
curl -b 'cookie' http://localhost:5007/set/key2 && echo "done2" &
curl -b 'cookie' http://localhost:5007/set/key3 && echo "done3" &
wait
# get result
curl -b 'cookie' http://localhost:5007/keys
$ sh test.sh
dict_keys(['_permanent'])
ok
ok
ok
done3
done1
done2
dict_keys(['_permanent', 'key2'])
$ sh test.sh
dict_keys(['_permanent'])
ok
done3
ok
ok
done2
done1
dict_keys(['_permanent', 'key1'])
为什么请求完成后所有键都不存在?