这是我的问题。我有一个 Flask 应用程序,它对某些数据集进行一些预测。用户可以将多个数据集上传到服务器并对任意数据集进行操作。
这里,我需要清理用户数据目录
static/files/userdata_<ip_of_client>/
如果用户 30 秒未连接,我将尝试删除整个目录。 仅供参考,客户端 JavaScript 每 10 秒使用 fetch 发送一个 POST 请求,因此如果错过 3 个窗口,文件将被清除。就是这个想法。
POST 请求触发具有如下代码的 API
@app.route("/api/ping", methods=["POST"])
def ping():
try:
client_ip = request.remote_addr
with data_lock:
folder_access_times[client_ip] = datetime.datetime.now()
这里 data_lock 是线程模块中全局声明的 Lock()
在另一个线程中,我正在检查是否有客户端在 30 秒内没有像这样连接
with data_lock:
curtime = datetime.datetime.now()
for key,val in folder_access_times.items():
diff = (curtime-val).seconds
if diff > 30:
shutil.rmtree(...)
问题是锁不能正常工作。注意到非常奇怪的行为,比如
即使我在这里使用 Lock 并且 ping API 成功修改了字典,但我注意到,即使 API 更新了很久之后,后台线程仍然可以看到旧数据。
数据非常不一致,因为当前日期也会在后台进程的下一次迭代中恢复到之前的日期(我在后台进程中使用 while 循环),这在锁定的情况下不是有意的。
不明白我错过了什么。 任何帮助将不胜感激。
如果您使用 Werkzeug 或 WSGI 与多个工作人员一起部署了 Flask 应用程序,您会遇到问题,因为每个工作人员都维护自己的字典,而该字典并非在所有工作人员之间共享。
为了解决这个问题,您可以在线程模式而不是多处理模式下运行应用程序,或者如果您更喜欢多处理,则需要在所有工作人员之间共享字典。这可以使用 multiprocessing.Manager() 来完成,如this
中所述