2014-01-24 30 views
1

我正在编写当前在Heroku上托管的python应用程序。它处于早期开发阶段,所以我使用一个网络测试仪免费帐户。不过,我希望我的重任务能够异步完成,所以我使用了铁工附加组件。我已经完成了所有设置,并且执行最简单的工作,例如发送电子邮件或任何不需要将任何数据发送回应用程序的任何工作。问题是:我如何将工作者输出从铁工人员发回我的应用程序?或者更好的是,我如何通知我的应用程序该工作人员完成了这项工作?铁工作业完成通知

我看了看其他的铁解决方案,如缓存和消息队列,但我能找到的唯一的事情是,我可以明确要求工作者状态。很明显,我不希望我的Web服务来调查工作人员,因为它有些挫败了将任务转移到背景的原始目的。我在这里错过了什么?

回答

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('/') 

注意,在我的情况下,得到的是这里只是为了测试,我不希望我的用户打这个端点,并调用任务。但是我可以想象这种情况实际上是有用的,特别是如果您不为任务使用任何类型的调度程序。

与端点准备好了,我开始寻找访问端点从工作人员的一种方式。我发现这个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

最简单的方法 - 推送消息到您的API从工人 - 这是你需要在你的应用程序日志或任何

+0

您能否提供一些更多详细信息?我可以推送什么样的消息?基本代码示例可能? – lawicko