APScheduler 在 Heroku 上托管的 Flask 应用程序中复制作业

问题描述

我有一个如下结构的应用程序,它允许用户安排任务来每天早上、下午等查询 FB API 以提取页面/发布数据(在这种情况下是凌晨 3 点)。

我遇到的问题是调度程序将每个作业执行两次,这显然是不可取的。奇怪的是,这个问题似乎不会在本地发生,只有在生产模式下,我在 Heroku 中托管这个,有 1 个 web dyno 和 1 个 worker dyno,每个只有 1 个进程。因此,我倾向于 Heroku 是问题所在。

我有一个页面来列出当前计划的作业,当我检查它时,刷新页面后,相同的作业实例将在两个不同的值之间滑动(下面的屏幕截图)。就好像有两个 BackgroundScheduler 的实例在运行。

enter image description here

enter image description here

我怀疑这是因为 BackgroundScheduler 被启动了两次(一次是在 flasky.py 中,一次是在 tasks.py 中)所以我创建了一个临时解决方案来停止 BackgroundScheduler 的双重初始化,但我仍然遇到同样的问题并且我现在卡住了。任何帮助将不胜感激。

-->app
   -->__init__.py
   -->decorators.py
   -->models.py
   -->tasks.py
   -->auth
      -->__init__.py
      -->errors.py
      -->forms.py
      -->views.py
   -->main
      -->__init__.py
      -->errors.py
      -->forms.py
      -->views.py
   -->static
   -->templates
-->migrations
config.py
flasky.py
procfile
requirements.txt

app/flasky.py

from flask import Flask,render_template,session,redirect,url_for,flash
import os
from app import create_app,db
from app.models import User,Role
from datetime import datetime
from flask_migrate import Migrate,upgrade

app = create_app(os.getenv('FLASK_CONfig') or 'default')

app/_ init _.py

from flask import Flask,render_template
from flask_bootstrap import Bootstrap
from flask_moment import Moment
from flask_migrate import Migrate
from flask_sqlalchemy import sqlAlchemy
from config import config
from flask_session import Session
from apscheduler.schedulers.background import BackgroundScheduler
from apscheduler.jobstores.sqlalchemy import sqlAlchemyJobStore
import rq
from redis import Redis
from flask_login import LoginManager
from worker import conn
import os

bootstrap = Bootstrap()
moment = Moment()
db = sqlAlchemy()
scheduler = BackgroundScheduler()
migrate = Migrate()
session= Session()
login_manager = LoginManager()
login_manager.login_view = 'auth.login'

def create_app(config_name='default'):
    app = Flask(__name__)
    app.config.from_object(config[config_name])
    db.init_app(app)
    bootstrap.init_app(app)
    moment.init_app(app)
    migrate.init_app(app,db)
    session.init_app(app)
    login_manager.init_app(app)
    if not scheduler.running:
        scheduler.start()
        jobstore_url = os.environ.get('DATABASE_URL')
        scheduler.add_jobstore(sqlAlchemyJobStore(url=jobstore_url),'sqlalchemy')

    from .main import main as main_blueprint
    from .auth import auth as auth_blueprint

    app.register_blueprint(main_blueprint)
    app.register_blueprint(auth_blueprint,url_prefix='/auth')

    app.task_queue = rq.Queue('flasky',connection=Redis.from_url(os.environ.get(REdis_URL)) 

    if app.config['SSL_REDIRECT']:
        from flask_sslify import SSLify
        sslify = SSLify(app)

    return app

app/tasks.py

from . import create_app,db
from .models import User,Tokens,Files
from .decorators import token_getter
from flask_login import current_user
import requests
import datetime as dt
import urllib
import os

app = create_app(os.getenv('FLASK_CONfig') or 'default')

<FUNCTIONS HERE>

app/auth/views.py

from flask import render_template,request,flash,current_app,Response
from .. import db,scheduler
from . import auth
from ..models import User,Role,Files
from flask_login import login_user,logout_user,login_required
from ..decorators import admin_required,token_setter,token_getter,permission_required
import requests
import urllib
from .forms import LoginForm,SubmitConnection,ScheduleJobForm
from app.tasks import refreshed_google_client,test_context

app/main/views.py

from flask import render_template,request
from datetime import datetime
from . import main
from .. import db,scheduler
from ..models import User,Tokens
from .forms import NameForm,AnalyticsForm
from flask_login import login_required,current_user
from ..decorators import admin_required,permission_required
import requests
import rq
from redis import Redis
from app.tasks import refreshed_google_client,load_analytics

@main.route('/ig_sync',methods=['GET','POST'])
@login_required
@permission_required(4)
def ig_sync():
    form = IGAnalyticsForm()
    
    if request.method=='POST':
        from app.tasks import load_ig_sync
        if form.validate_on_submit():
            if form.submit_analytics_schedule.data:
                #GET VARIABLES FROM FORM
                scheduler.add_job(func=load_ig_sync,args=[#VARIABLES HERE],trigger='cron',hour=3,id=f'SYNC_IG_{page_name}',jobstore='sqlalchemy')
                return(redirect(url_for('main.job_schedule')))
    return render_template('ig_sync.html',form=form)

应用程序/procfile

web: gunicorn flasky:app
worker: rq worker -u $REdis_URL flasky

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...