铁工工作完成通知

时间:2014-01-24 16:59:37

标签: python heroku notifications worker

我正在编写目前正在Heroku上托管的python应用程序。它处于早期开发阶段,因此我使用一个网络dyno的免费帐户。尽管如此,我还是希望我的重任务能够异步完成,所以我正在使用铁工作者插件。我完成了这一切,它完成了最简单的工作,如发送电子邮件或任何不需要将任何数据发送回应用程序的工作。问题是:如何将工人输出从铁工人发送回我的应用程序?或者更好的是,如何通知我的应用程序工作人员完成了这项工作?

我查看了缓存和消息队列等其他铁解决方案,但我唯一能找到的就是我可以明确地询问工作状态。显然,我不希望我的Web服务对工作者进行轮询,因为它有点破坏了将任务移动到后台的最初目的。我在这里缺少什么?

2 个答案:

答案 0 :(得分:2)

我认为这个问题在谷歌很高,所以如果你来这里希望找到更多细节,这就是我最终做的事情:

首先,我在我的应用上准备了端点。我的应用使用Flask,因此这就是代码的外观:

@app.route("/worker", methods=["GET", "POST"])
def worker():
#refresh the interface or whatever is necessary
    if flask.request.method == 'POST':
        return 'Worker endpoint reached'
    elif flask.request.method == 'GET':
        worker = IronWorker()
        task = worker.queue(code_name="hello", payload={"WORKER_DB_URL": app.config['WORKER_DB_URL'],
                            "WORKER_CALLBACK_URL": app.config['WORKER_CALLBACK_URL']})
        details = worker.task(task)
        flask.flash("Work queued, response: ", details.status)
        return flask.redirect('/')

请注意,在我的情况下,GET仅用于测试,我不希望我的用户点击此端点并调用该任务。但是我可以想象这实际上有用的情况,特别是如果你没有为你的任务使用任何类型的调度程序。

在端点准备就绪后,我开始寻找一种从工作者访问该端点的方法。我找到了这个fantastic requests library并在我的工作人员中使用它:

import sys, json
from sqlalchemy import *
import requests

print "hello_worker initialized, connecting to database..."

payload = None
payload_file = None
for i in range(len(sys.argv)):
    if sys.argv[i] == "-payload" and (i + 1) < len(sys.argv):
        payload_file = sys.argv[i + 1]
        break

f = open(payload_file, "r")
contents = f.read()
f.close()

payload = json.loads(contents)

print "contents: ", contents
print "payload as json: ", payload

db_url = payload['WORKER_DB_URL']

print "connecting to database ", db_url

db = create_engine(db_url)
metadata = MetaData(db)

print "connection to the database established"

users = Table('users', metadata, autoload=True)
s = users.select()

#def run(stmt):
#    rs = stmt.execute()
#    for row in rs:
#        print row

#run(s)

callback_url = payload['WORKER_CALLBACK_URL']
print "task finished, sending post to ", callback_url
r = requests.post(callback_url)
print r.text

所以最后这里没有真正的魔力,唯一重要的是如果你需要在任务完成时通知你的页面,就在有效负载中发送回调url。或者,如果在应用程序中使用端点URL,则可以将端点URL放在数据库中。顺便说一句。上面的剪辑还显示了如何连接到worker中的postgresql数据库并打印所有用户。

您需要注意的最后一件事是如何格式化.worker文件,我的看起来像这样:

# set the runtime language. Python workers use "python"
runtime "python"
# exec is the file that will be executed:
exec "hello_worker.py"
# dependencies
pip "SQLAlchemy"
pip "requests"

这将安装最新版本的SQLAlchemy和请求,如果您的项目依赖于库的任何特定版本,则应该这样做:

pip "SQLAlchemy", "0.9.1"

答案 1 :(得分:-1)

最简单的方法 - 将消息从工作人员推送到您的api - 它的日志或您在应用中需要的任何内容