使用atexit()关闭Flask应用时删除AstraDB表触发RuntimeError
问题:Flask关闭时删除AstraDB表出现RuntimeError报错
我在Flask应用中通过atexit()注册了删除AstraDB表的函数,代码如下:
app = Flask(__name__) # AstraDB connection and vector store initialization def initialize_astra_vector_store(): cassio.init(token=ASTRA_DB_APPLICATION_TOKEN, database_id=ASTR_DB_ID) embedding = OpenAIEmbeddings(openai_api_key=OPENAI_API_KEY) astra_vector_store = Cassandra( embedding=embedding, table_name=table_name, session=None, keyspace=None ) print('----------------------table created as table_name:', table_name) return astra_vector_store # flask app routes ... def delete_table(): print('----------------------inside delete_table') db = AstraDB( token=os.getenv('ASTRA_DB_APPLICATION_TOKEN'), api_endpoint='<api-endpoint>', ) print('----------------------table_name:', table_name) # Drop the table created for this session db.delete_collection(collection_name=table_name) print("----------------------APP EXITED----------------------") atexit.register(delete_table) if __name__ == '__main__': app.run(debug=False)
关闭应用时,AstraDB中的表已成功删除,但出现如下错误:
Exception in thread Task Scheduler: Traceback (most recent call last): File "C:\Users\HP\AppData\Local\Programs\Python\Python311\Lib\threading.py", line 1038, in _bootstrap_inner self.run() File "cassandra\cluster.py", line 4239, in cassandra.cluster._Scheduler.run File "C:\Users\HP\AppData\Local\Programs\Python\Python311\Lib\concurrent\futures\thread.py", line 167, in submit raise RuntimeError('cannot schedule new futures after shutdown') RuntimeError: cannot schedule new futures after shutdown Exception in thread Task Scheduler: Traceback (most recent call last): File "C:\Users\HP\AppData\Local\Programs\Python\Python311\Lib\threading.py", line 1038, in _bootstrap_inner self.run() File "cassandra\cluster.py", line 4239, in cassandra.cluster._Scheduler.run File "C:\Users\HP\AppData\Local\Programs\Python\Python311\Lib\concurrent\futures\thread.py", line 167, in submit raise RuntimeError('cannot schedule new futures after shutdown') RuntimeError: cannot schedule new futures after shutdown
解决方案
显式关闭Cassandra会话:在删除表操作前,先关闭初始化时创建的Cassandra会话,避免其线程池在程序 shutdown 后仍尝试调度任务。修改
delete_table函数:def delete_table(): print('----------------------inside delete_table') # 关闭Cassandra会话 from cassio.config import check_resolve_session session = check_resolve_session() if session: session.shutdown() # 执行删除表操作 db = AstraDB( token=os.getenv('ASTRA_DB_APPLICATION_TOKEN'), api_endpoint='<api-endpoint>', ) print('----------------------table_name:', table_name) db.delete_collection(collection_name=table_name) print("----------------------APP EXITED----------------------")改用Flask的应用上下文销毁钩子:放弃
atexit,使用Flask原生的teardown_appcontext装饰器,它更贴合Web应用的生命周期,能避免线程调度冲突:@app.teardown_appcontext def delete_table(error=None): print('----------------------inside delete_table') # 关闭Cassandra会话 from cassio.config import check_resolve_session session = check_resolve_session() if session: session.shutdown() # 执行删除表操作 db = AstraDB( token=os.getenv('ASTRA_DB_APPLICATION_TOKEN'), api_endpoint='<api-endpoint>', ) print('----------------------table_name:', table_name) db.delete_collection(collection_name=table_name) print("----------------------APP EXITED----------------------")注意:删除原来的
atexit.register(delete_table)代码。遵循资源释放顺序:始终先关闭数据库会话,再执行删除操作,确保Cassandra的线程池不会在程序 shutdown 阶段继续提交任务,从根源上消除报错。
内容的提问来源于stack exchange,提问作者Hamza Khan
相关产品推荐
相关产品推荐

