Flask耗时任务编写记录
写完3分钟,调试半小时……

在编写Flask后端时,遇到了一个常见的问题:
前端通过API请求后端执行耗时操作时拿不到后端的“成功调起”返回。

之前遇到的都是耗时操作,不管多久都等。最后的解决方案就是Nginx和前端延长超时时间。
这次遇到的是只需要立马返回,耗时操作可以放到后面执行。

这就轮到线程入场了。这里直接用掘金搜到的最简代码
掘金原文

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
from flask import Flask
from time import sleep
from concurrent.futures import ThreadPoolExecutor
# DOCS https://docs.python.org/3/library/concurrent.futures.html#concurrent.futures.ThreadPoolExecutor
# 创建线程池执行器
executor = ThreadPoolExecutor(2)
app = Flask(__name__)
@app.route('/jobs')
def run_jobs():
 # 交由线程去执行耗时任务
 executor.submit(long_task, 'hello', 123)
 return 'long task running.'
# 耗时任务
def long_task(arg1, arg2):
 print("args: %s %s!" % (arg1, arg2))
 sleep(5)
 print("Task is done!")
if __name__ == '__main__':
 app.run()

但是在实现过程中遇到了难以调试的问题……
因为交给线程执行了,如果途中某个方法挂掉了,后端flask不会返回报错(因为早就把response吐出去了)。
调试异常艰难,不过最后想出来的解决方案也很简单(捂脸

  1. 打log做标记,能看到具体执行到了哪儿,以及到哪儿就停了。但是治标不治本,没有报错
  2. 调试时,不使用线程。Debug完后再启用线程

有条件的情况下,直接用2,治标又治本,迅速搞定。