我想提供一个能够同时处理多个用户请求的falcon API。每个请求都会触发一个长时间的处理任务,因此我使用了来自concurrent.futures
的ThreadPoolExecutor
,如下所示:
import falcon
from concurrent.futures import ThreadPoolExecutor
executor = ThreadPoolExecutor(max_workers=10)
class Resource:
def on_post(self, req, resp):
def some_long_task():
# here is the code for the long task
executor.submit(some_long_task)
resp.body = 'OK'
resp.status = falcon.HTTP_201
app = falcon.App()
resource = Resource()
app.add_route('/', resource)
# Serve...
我使用gunicorn
来提供API,参数如下:gunicorn main:app --timeout 10000
。
当我连续执行两个对API的请求时,两个长任务都是在后台连续触发的。但是,一旦启动的第一个长任务完成,它就会停止执行第二个任务。我怎样才能避免这种情况?
发布于 2021-11-26 21:28:42
通过用time.sleep(10)
替换您的长时间运行的任务,我无法重现您的问题:
import logging
import time
import uuid
import falcon
from concurrent.futures import ThreadPoolExecutor
logging.basicConfig(
format='%(asctime)s [%(levelname)s] %(message)s', level=logging.INFO)
executor = ThreadPoolExecutor(max_workers=10)
class Resource:
def on_post(self, req, resp):
def some_long_task():
# here is the code for the long task
time.sleep(10)
logging.info(f'[task {taskid}] complete')
taskid = str(uuid.uuid4())
executor.submit(some_long_task)
logging.info(f'[task {taskid}] submitted')
resp.media = {'taskid': taskid}
resp.status = falcon.HTTP_ACCEPTED
app = falcon.App()
resource = Resource()
app.add_route('/', resource)
正如预期的那样,所有任务都正确运行到完成:
[2021-11-26 21:45:25 +0100] [8242] [INFO] Starting gunicorn 20.1.0
[2021-11-26 21:45:25 +0100] [8242] [INFO] Listening at: http://127.0.0.1:8000 (8242)
[2021-11-26 21:45:25 +0100] [8242] [INFO] Using worker: sync
[2021-11-26 21:45:25 +0100] [8244] [INFO] Booting worker with pid: 8244
2021-11-26 21:45:29,565 [INFO] [task 5b45b1f5-15ac-4628-94d8-3e1fd0710d21] submitted
2021-11-26 21:45:31,133 [INFO] [task 4553e018-cfc6-4809-baa4-f873579a9522] submitted
2021-11-26 21:45:33,724 [INFO] [task c734d89e-5f75-474c-ad78-59f178eef823] submitted
2021-11-26 21:45:39,575 [INFO] [task 5b45b1f5-15ac-4628-94d8-3e1fd0710d21] complete
2021-11-26 21:45:41,142 [INFO] [task 4553e018-cfc6-4809-baa4-f873579a9522] complete
2021-11-26 21:45:43,735 [INFO] [task c734d89e-5f75-474c-ad78-59f178eef823] complete
问题会不会出在你的长任务代码中?
有一些不是微不足道的陷阱需要注意:
executor
,而不检查实际结果,这可能会掩盖任务中的异常,这可能看起来像是停止执行。也许完成第一个任务会在第二个任务中引发异常?尝试用一个try... except
来包围你的任务,我自己从来没有遇到过这个问题,但是从并行线程导入可能会导致死锁,例如,ThreadPoolExecutor + Requests == deadlock?这通常不应该是一个问题,但它可能是由并行任务试图在运行时导入插件造成的,就像在请求的情况下。https://stackoverflow.com/questions/70055448
复制相似问题