Flask应用程序启动后如何执行任务?

时间:2019-09-30 23:44:45

标签: python heroku flask flask-sqlalchemy

我正在尝试在应用程序与端口绑定之后执行任务,以免它因启动时间太长而被Heroku杀死。我知道before_first_request的存在,但是我希望在应用启动后尽快执行此操作,而无需请求。

我正在将一个对象作为应用程序对象的属性加载(因为我需要跨请求访问它),并且该对象必须以一种奇怪的方式进行初始化(它检查文件是否存在,如果不存在则下载文件)然后执行一堆计算。

目前,我正在通过以下方式进行操作:

def create_app() -> Flask:
    ...
    with app.app_context():
        app.model = RecommenderModel()  # This downloads a pretty heavy file if it isn't there
        app.model.load_products()  # This performs a bunch of calculations
    ...
    return app

这会正确初始化应用程序(在本地测试),但是Heroku会因为花费太长时间而将其杀死(错误R10)。

有没有一种异步方法?当我尝试这样做时,应用程序上下文丢失了。

编辑:有关我在做什么的其他信息:

RecommenderModel对象为推荐系统的逻辑建模。到目前为止,这些建议基于矢量余弦相似度。这些向量是使用预训练的word2vec嵌入(这是需要下载的大文件)提取的。从乘积到向量的转换由Preprocessor类处理。

推荐模型初始化如下:

class RecommenderModel(object):
    def __init__(self) -> None:
        self.preproc = Preprocessor()
        self.product_vector: dict = {}

    def load_products(self) -> None:
        for product in Product.get_all():
            self.product_vector[product.id] = self.preproc.compute_vector(product)

预处理器初始化如下:

class Preprocessor(object):
    def __init__(self, embeddings: str = embeddings) -> None:
        S3.ensure_file(embeddings)
        self.vectors = KeyedVectors.load_word2vec_format(embeddings)

S3.ensure_file方法基本上检查文件是否存在,如果不存在,则下载该文件:

class S3(object):
    client = boto3.client('s3')

    @classmethod
    def ensure_file(cls, filepath: str) -> None:
        if os.path.exists(filepath):
            return
        dirname, filename = os.path.split(filepath)
        bucket_name = os.environ.get('BUCKET_NAME')
        cls.client.download_file(bucket_name, filename, filepath)

0 个答案:

没有答案