我正在尝试运行一个包含以下内容的Flask
应用程序:
SQLalchemy
数据库1
和2
作为后台进程运行为此,我有以下代码:
from flask import Flask
from flask import current_app
import concurrent.futures
from concurrent.futures import ThreadPoolExecutor
import queue
app = Flask(__name__)
q = queue.Queue()
def build_cache():
# 1. Yielding API requests on the fly
track_and_features = spotify.query_tracks() # <- a generator
while True:
q.put(next(track_and_features))
def upload_cache(tracks_and_features):
# 2. Uploading each request to a `SQLalchemy` database
with app.app_context():
Upload_Tracks(filtered_dataset=track_and_features)
return "UPLOADING TRACKS TO DATABASE"
@app.route('/cache')
def cache():
# 3. Do `1` and `2` as a background process
with concurrent.futures.ThreadPoolExecutor() as executor:
future_to_track = {executor.submit(build_cache): 'TRACKER DONE'}
while future_to_track:
# check for status of the futures which are currently working
done, not_done = concurrent.futures.wait(
future_to_track,
timeout=0.25,
return_when=concurrent.futures.FIRST_COMPLETED)
# if there is incoming work, start a new future
while not q.empty():
# fetch a track from the queue
track = q.get()
# Start the load operation and mark the future with its TRACK
future_to_track[executor.submit(upload_cache, track)] = track
# process any completed futures
for future in done:
track = future_to_track[future]
try:
data = future.result()
except Exception as exc:
print('%r generated an exception: %s' % (track, exc))
del future_to_track[future]
return 'Cacheing playlist in the background...'
以上所有方法均可,但不能作为后台处理。调用cache()
时,该应用程序挂起,仅在该过程完成后才恢复运行。
我用gunicorn -c gconfig.py app:app -w 4 --threads 12
我在做什么错了?
编辑:如果为了简化起见,请对其进行调试,并简单地编写:
# 1st background process
def build_cache():
# only ONE JOB
tracks_and_features = spotify.query_tracks() # <- not a generator
while True:
print next(tracks_and_features)
# background cache
@app.route('/cache')
def cache():
executor.submit(build_cache)
return 'Cacheing playlist in the background...'
该过程在后台运行。
但是,如果我添加另一个作业:
def build_cache():
tracks_and_features = spotify.query_tracks()
while True:
Upload_Tracks(filtered_dataset=next(tracks_and_features) #SQLalchemy db
背景不再起作用。
简而言之:
背景仅在我一次运行一项作业时才起作用(这是首先使用队列的想法的局限性)。
似乎不知道该问题是将后台进程绑定到SQLalchemy。在这里完全迷路了。
答案 0 :(得分:2)
仍然不确定您的意思
我的意思是,应用程序等待登录时发出的所有请求,然后才进入主页。它应该立即转到主页,并在后台发出请求
这里有几个问题:
UploadTracks
正在写入数据库,则表上可能有锁。检查索引并检查数据库中的锁定等待时间。UploadTracks
正在等待第一个返回其连接。在您的第一个示例中,端点在等待所有期货完成后才返回,而在您的第二个示例中,端点在将任务提交给执行者后立即返回。如果您希望烧瓶在任务仍在后台线程中运行时快速响应,请删除with concurrent.futures.ThreadPoolExecutor() as executor:
并在模块顶部构造一个全局线程池。
上下文管理器使用with
等待所有提交的任务,然后退出,但是我不确定这是否是您的主要问题。
答案 1 :(得分:1)
尝试在路由处理程序之外创建Form
。
ThreadPoolExecutor