当我的Flask应用收到请求时,它会生成一个对象,该对象将消息添加到队列中,并在另一个线程上安排队列轮询作业。每两秒钟,对队列进行轮询以查找要发送的消息。某些消息需要数据库查询。在app.py文件中,一个while循环检查消息是否留在队列中,然后休眠直到队列中没有消息,然后提交。
问题是,这引发了QueuePool限制错误。我使用svn
检查了PostGreSQL数据库,并且队列轮询作业中的查询在事务中处于空闲状态。我检查了一下,并且所使用的scoped_session始终相同。确实,一旦队列为空,也将调用提交。那么问题可能是什么?
请注意,我使用APScheduler进行调度。
我知道此实现没有意义:我不想在消息之间调用time.sleep(),但还没有意识到我仍然需要阻塞主线程,以便提交能够正常工作。但是,无论实施有多危险,问题仍然是合法的。
简单的例子:
application.py
svnsync
queueing.py
SELECT * FROM pg_stat_activity
config.py
import time
from config import FlaskDatabaseConfig
from queueing import Queue
from flask import Flask
from flask import request
from flask_migrate import Migrate
from flask_sqlalchemy import SQLAlchemy
application = Flask(__name__)
application.config.from_object(FlaskDatabaseConfig())
db = SQLAlchemy(application)
application.route("/", methods=['GET'])
def handle_req():
queue = Queue()
for i in range(3):
queue.add_message("Test", 1)
while len(queue.messages) > 0:
time.sleep(1)
db.session.commit()
# run the app.
if __name__ == "__main__":
application.run(debug=False, port=5001)
models.py
from application import db
from models import User
from apscheduler.schedulers.background import BlockingScheduler, BackgroundScheduler
from apscheduler.triggers.interval import IntervalTrigger
class Queue():
def __init__(self):
self.messages = []
self.job = None
def add_message(self, message, recipient_index):
self.messages.append((message, recipient_index))
if not self.job:
scheduler = BackgroundScheduler()
scheduler.start()
job = scheduler.add_job(
func=self.poll_queue,
trigger=IntervalTrigger(
seconds=2
),
id='poll_queue',
name='The queue is polled every 2 seconds for sending messages',
replace_existing=True,
misfire_grace_time=10)
self.job = job
def poll_queue(self):
if len(self.messages)>0:
msg, recipient_index = self.messages.pop(0)
recipient = User.query.get(recipient_index)
self.send_message(msg, recipient)
else:
self.job.remove()
def send_message(self):
pass