如何在Heroku中运行后台任务?

时间:2020-10-22 03:32:36

标签: python selenium-webdriver heroku request background-process

我已经构建了一个python应用程序,并使用FlaskPython进行了部署。这是我代码的Skelton。

#app.py
@app.route('/', methods=['GET'])
def login():
    '''login process'''

@app.route('/reset-password', methods=['GET'])
def reset_password():
    '''reset password process'''

@app.route('/add-psa', methods=['GET'])
def add_user():
    '''add user process'''

if __name__ == '__main__':
    app.debug = True
    app.run(use_reloader=False, threaded=True)

已部署的应用程序在Heroku中工作正常。但有时需要30秒钟以上才能做出响应,根据Heroku doc,这意味着H12 error。因此,我按照this教程进行了后台作业。 这是我到目前为止所做的

#worker.py
import os

import redis
from rq import Worker, Queue, Connection

listen = ['high', 'default', 'low']

redis_url = os.getenv('REDISTOGO_URL', 'redis://localhost:6379')

conn = redis.from_url(redis_url)

if __name__ == '__main__':
    with Connection(conn):
        worker = Worker(map(Queue, listen))
        worker.work()

下一步...

#utils.py
import requests

def count_words_at_url(url):
    resp = requests.get(url)
    return len(resp.text.split())

我还更改了Procfilerequirements.txt

我想在后台运行我的reset_password(),因为它花费的时间超过30seconds。有人可以帮助我吗?

1 个答案:

答案 0 :(得分:2)

一种解决方案是从Web请求中生成线程:在这种情况下,可以在后台线程启动并执行必要的任务(不受HTTP超时限制)的同时立即返回(几乎)响应。

# my background thread
class MyWorker():

  def __init__(self, message):
    self.message = message

    thread = threading.Thread(target=self.run, args=())
    thread.daemon = True
    thread.start()

  def run(self):
    logging.info(f'run MyWorker with parameter {self.message}')

    # do something

Web请求创建线程的实例,并可以通知调用方正在进行的操作(或应用其他工作流/消息)

#app.py
@app.route('/reset-password', methods=['GET'])
def reset_password():
'''reset password process'''
   MyWorker('param_value')
   return "In progress... You will receive an email"