簡體   English   中英

使用 Flask 的“應用程序”singleton 到 Dask Scheduler/Workers

[英]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() 設置應用程序上下文。

我們嘗試過:

  • 在應用程序 singleton 創建上推送app_context ( app.app_context().push() )。
  • with current_app.app_context():在 CLI 命令和一些使用current_app的函數上。
  • 通過 Dask 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM