JLT*_*hiu 7 python asynchronous web-services twisted klein-mvc
我的python Twisted Klein Web服务中有两个函数:
@inlineCallbacks
def logging(data):
ofile = open("file", "w")
ofile.write(data)
yield os.system("command to upload the written file")
@APP.route('/dostuff')
@inlineCallbacks
def dostuff():
yield logging(data)
print "check!"
returnValue("42")
Run Code Online (Sandbox Code Playgroud)
当os.system("command to upload the written file")
运行时,它会显示消息说"开始上传",然后"上传完成".我想使日志记录功能异步,以便在logging
处理dostuff
程序打印出"check!" 之后处理器中的处理.(我实际上希望在returnValue("42")之后进行处理,但是我认为这两者都使得日志记录功能异步?)
我认为yield语句会使它无阻塞,但似乎并非如此,"检查!" 始终在"开始上传"和"上传完成"后打印.我很感激,如果有人可以给我一些反馈意见,因为我是异步编码的新手并且暂时被阻止了...
要使代码异步,您需要使用Twisted Deferreds,如此处所述。Deferreds 为您提供了用于异步代码执行的 API,它们允许您将回调附加到函数,并在由reactor对象管理的 Twisted 事件循环中执行代码。
我发现在您的情况下有两种使用 Deferreds 的潜在方法。
1)在后台执行任务reactor.callLater()
dostuff
如果处理程序不关心结果,这是可以的。您可以使用reactor.callLater()。这样,您的异步函数将在您从 中返回值后执行doStuff
。
所以像这样:
from klein import run, route, Klein
from twisted.internet import defer, task, reactor
import os
app = Klein()
def logging(data):
ofile = open("file", "w")
ofile.write(data)
result = os.system("ls")
print(result)
@route('/')
def dostuff(request):
reactor.callLater(0, logging, "some data")
print("check!")
return b'Hello, world!'
run("localhost", 8080)
Run Code Online (Sandbox Code Playgroud)
此代码的事件顺序如下,首先打印“check”,然后返回“hello world”响应,最后异步调用成功并打印运行结果os.system()
。
2016-08-11 08:52:33+0200 [-] check!
2016-08-11 08:52:33+0200 [-] "127.0.0.1" - - [11/Aug/2016:06:52:32 +0000] "GET / HTTP/1.1" 200 13 "-" "curl/7.35.0"
a.py file
Run Code Online (Sandbox Code Playgroud)
2)在后台执行任务并获取结果task.deferLater()
如果您关心“日志记录”功能的结果,您还可以将回调附加到该对象并使用twisted.internet.task API。如果你想这样做,你需要重构你的处理程序以像这样工作
@route('/')
def dostuff(request):
def the_end(result):
print("executed at the end with result: {}".format(result))
dfd = task.deferLater(reactor, 0, logging, "some data")
dfd.addCallback(the_end)
print("check!")
return b'Hello, world!'
Run Code Online (Sandbox Code Playgroud)
这样事件的顺序将与上面相同,但the_end
函数将在函数完成后最后执行logging
。
2016-08-11 08:59:24+0200 [-] check!
2016-08-11 08:59:24+0200 [-] "127.0.0.1" - - [11/Aug/2016:06:59:23 +0000] "GET / HTTP/1.1" 200 13 "-" "curl/7.35.0"
a.py file
2016-08-11 08:59:24+0200 [-] executed at the end with result: some result
Run Code Online (Sandbox Code Playgroud)