[英]Use Flask's “app” singleton to Dask Scheduler/Workers
案子:
我們有一些耗時的功能/集成測試,它們利用 Flask 的current_app
進行配置(全局變量等)和一些日志記錄。
我們正在嘗試在集群上分發和並行化這些測試(目前是從Dask 的 Docker 映像創建的本地“集群”。)。
問題?):
讓我們假設以下示例:
一個耗時的function:
def will_take_my_time(n)
# Add the 'TAKE_YOUR_TIME' in the config in how many seconds you want
time.sleep(current_app.config['TAKE_YOUR_TIME'])
return n
耗時的測試:
def need_my_time_test(counter=None):
print(f"Test No. {will_take_my_time(counter)}")
一個 Flask CLI 命令,它創建一個 Dask Client
以連接到集群並執行 10 次need_my_time_test
測試:
@app.cli.command()
def itests(extended):
with Client(processes=False) as dask_client:
futures = dask_client.map(need_my_time_test, range(10))
print(f"Futures: {futures}")
print(f"Gathered: {dask_client.gather(futures)}")
編輯:為方便起見,讓我們添加一個應用程序工廠以獲得更容易重現的示例:
def create_app():
app = Flask(__name__)
app.config.from_mapping(
SECRET_KEY='dev',
DEBUG=True,
)
@app.route('/hello')
def hello():
return 'Hello, World!'
@app.cli.command()
def itests(extended):
with Client(processes=False) as dask_client:
futures = dask_client.map(need_my_time_test, range(10))
print(f"Futures: {futures}")
print(f"Gathered: {dask_client.gather(futures)}")
將上述內容與flask itests
使用,我們遇到以下錯誤(在此處描述):
RuntimeError:在應用程序上下文之外工作。
這通常意味着您試圖以某種方式使用與當前應用程序 object 交互所需的功能。 要解決此問題,請使用 app.app_context() 設置應用程序上下文。
我們嘗試過:
app_context
( app.app_context().push()
)。with current_app.app_context():
在 CLI 命令和一些使用current_app
的函數上。Variable
發送app_context
但它不能序列化上下文。無濟於事。
問題:
使用current_app
代理時,假設 Flask 應用程序是在使用代理的同一進程中創建的。
這不是運行提交給工作人員的任務時的情況。 任務的執行與在提交任務的進程中創建的 Flask 應用程序隔離開來。
在任務中,定義 flask 應用程序並在那里提供應用程序上下文。
import time
from flask import Flask
from dask.distributed import Client
def _create_app():
app = Flask(__name__)
app.config.from_mapping(
SECRET_KEY='dev',
DEBUG=True,
TAKE_YOUR_TIME=0.2
)
return app
def will_take_my_time(n):
# Add the 'TAKE_YOUR_TIME' in the config in how many seconds you want
app = _create_app()
with app.app_context():
time.sleep(app.config['TAKE_YOUR_TIME'])
return n
def need_my_time_test(counter=None):
print(f"Test No. {will_take_my_time(counter)}")
def create_app():
app = _create_app()
@app.route('/hello')
def hello():
return 'Hello, World!'
@app.cli.command()
def itests():
with Client(processes=False) as dask_client:
futures = dask_client.map(need_my_time_test, range(10))
print(f"Futures: {futures}")
print(f"Gathered: {dask_client.gather(futures)}")
return app
app = create_app()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.