我正在编写目前正在Heroku上托管的python应用程序。它处于早期开发阶段,因此我使用一个网络dyno的免费帐户。尽管如此,我还是希望我的重任务能够异步完成,所以我正在使用铁工作者插件。我完成了这一切,它完成了最简单的工作,如发送电子邮件或任何不需要将任何数据发送回应用程序的工作。问题是:如何将工人输出从铁工人发送回我的应用程序?或者更好的是,如何通知我的应用程序工作人员完成了这项工作?
我查看了缓存和消息队列等其他铁解决方案,但我唯一能找到的就是我可以明确地询问工作状态。显然,我不希望我的Web服务对工作者进行轮询,因为它有点破坏了将任务移动到后台的最初目的。我在这里缺少什么?
答案 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 - 它的日志或您在应用中需要的任何内容