Ejemplo n.º 1
0
    def provide_celery(self, app: Flask) -> Celery:
        celery = Celery(
            app.import_name,
            backend=app.config["CELERY_RESULT_BACKEND"],
            broker=app.config["CELERY_BROKER_URL"],
        )
        celery.conf["CELERYD_HIJACK_ROOT_LOGGER"] = False
        celery.conf["CELERY_IMPORTS"] = (
            "matcher.tasks.export",
            "matcher.tasks.import_",
            "matcher.tasks.object",
        )
        celery.conf.update(app.config)
        celery.conf.ONCE = {
            "backend": "celery_once.backends.Redis",
            "settings": {
                "url": app.config["CELERY_RESULT_BACKEND"],
                "default_timeout": 60 * 60,
            },
        }

        class ContextTask(Task):
            def __call__(self, *args, **kwargs):
                with app.app_context():
                    return self.run(*args, **kwargs)

        class OnceTask(QueueOnce):
            def __call__(self, *args, **kwargs):
                with app.app_context():
                    return self.run(*args, **kwargs)

        celery.Task = ContextTask
        celery.OnceTask = OnceTask

        def handle_celery_postrun(retval=None, *args, **kwargs):
            """After each Celery task, teardown our db session"""
            if app.config["SQLALCHEMY_COMMIT_ON_TEARDOWN"]:
                if not isinstance(retval, Exception):
                    db.session.commit()
            # If we aren't in an eager request (i.e. Flask will perform teardown), then teardown
            if not app.config["CELERY_ALWAYS_EAGER"]:
                db.session.remove()

        task_postrun.connect(handle_celery_postrun)

        return celery