我使用Twisted Klein是因为框架的承诺之一是它是异步的,但是我测试了我开发的应用程序和一些测试代码,框架行为似乎是同步的。在
测试服务器代码为:
# -*- encoding: utf-8 -*-
import json
import time
from datetime import datetime
from klein import Klein
app = Klein()
def setHeader(request, content_type):
request.setHeader('Access-Control-Allow-Origin', '*')
request.setHeader('Access-Control-Allow-Methods', 'GET')
request.setHeader('Access-Control-Allow-Headers', 'x-prototype-version,x-requested-with')
request.setHeader('Access-Control-Max-Age', 2520)
request.setHeader('Content-type', content_type)
def cleanParams(params):
for key in params.keys():
param = params[key]
params[key] = param[0]
return params
@app.route('/test/', methods=["GET"])
def test(request):
setHeader(request,'application/json')
time.sleep(5)
return json.dumps([str(datetime.now())])
if __name__ == "__main__":
app.run(host='0.0.0.0',port=12030)
试验要求是:
^{pr2}$服务器启动后,如果我单独运行第二个代码:
2016-07-19 12:50:53.530000
2016-07-19 12:50:58.570000 [u'2016-07-19 12:50:58.548000']
2016-07-19 12:51:03.604000 [u'2016-07-19 12:51:03.589000']
2016-07-19 12:51:08.634000 [u'2016-07-19 12:51:08.625000']
2016-07-19 12:51:13.670000 [u'2016-07-19 12:51:13.654000']
2016-07-19 12:51:18.717000 [u'2016-07-19 12:51:18.708000']
2016-07-19 12:51:23.764000 [u'2016-07-19 12:51:23.748000']
很好,但是如果我同时运行两个实例:
实例1:
2016-07-19 12:53:05.025000
2016-07-19 12:53:10.057000 [u'2016-07-19 12:53:10.042000']
2016-07-19 12:53:20.113000 [u'2016-07-19 12:53:20.097000']
2016-07-19 12:53:30.181000 [u'2016-07-19 12:53:30.166000']
2016-07-19 12:53:40.236000 [u'2016-07-19 12:53:40.219000']
2016-07-19 12:53:50.316000 [u'2016-07-19 12:53:50.294000']
2016-07-19 12:54:00.381000 [u'2016-07-19 12:54:00.366000']
实例2:
2016-07-19 12:53:05.282000
2016-07-19 12:53:15.074000 [u'2016-07-19 12:53:15.059000']
2016-07-19 12:53:25.141000 [u'2016-07-19 12:53:25.125000']
2016-07-19 12:53:35.214000 [u'2016-07-19 12:53:35.210000']
2016-07-19 12:53:45.270000 [u'2016-07-19 12:53:45.255000']
2016-07-19 12:53:55.362000 [u'2016-07-19 12:53:55.346000']
2016-07-19 12:54:05.402000 [u'2016-07-19 12:54:05.387000']
以及服务器输出:
2016-07-19 12:53:10-0400 [-] "192.168.50.205" - - [19/Jul/2016:16:53:04 +0000] "GET /test/ HTTP/1.1" 200 30 "-" "python-requests/2.9.1"
2016-07-19 12:53:15-0400 [-] "192.168.50.205" - - [19/Jul/2016:16:53:10 +0000] "GET /test/ HTTP/1.1" 200 30 "-" "python-requests/2.9.1"
2016-07-19 12:53:20-0400 [-] "192.168.50.205" - - [19/Jul/2016:16:53:15 +0000] "GET /test/ HTTP/1.1" 200 30 "-" "python-requests/2.9.1"
2016-07-19 12:53:25-0400 [-] "192.168.50.205" - - [19/Jul/2016:16:53:20 +0000] "GET /test/ HTTP/1.1" 200 30 "-" "python-requests/2.9.1"
2016-07-19 12:53:30-0400 [-] "192.168.50.205" - - [19/Jul/2016:16:53:25 +0000] "GET /test/ HTTP/1.1" 200 30 "-" "python-requests/2.9.1"
2016-07-19 12:53:35-0400 [-] "192.168.50.205" - - [19/Jul/2016:16:53:30 +0000] "GET /test/ HTTP/1.1" 200 30 "-" "python-requests/2.9.1"
2016-07-19 12:53:40-0400 [-] "192.168.50.205" - - [19/Jul/2016:16:53:35 +0000] "GET /test/ HTTP/1.1" 200 30 "-" "python-requests/2.9.1"
2016-07-19 12:53:45-0400 [-] "192.168.50.205" - - [19/Jul/2016:16:53:40 +0000] "GET /test/ HTTP/1.1" 200 30 "-" "python-requests/2.9.1"
2016-07-19 12:53:50-0400 [-] "192.168.50.205" - - [19/Jul/2016:16:53:45 +0000] "GET /test/ HTTP/1.1" 200 30 "-" "python-requests/2.9.1"
2016-07-19 12:53:55-0400 [-] "192.168.50.205" - - [19/Jul/2016:16:53:50 +0000] "GET /test/ HTTP/1.1" 200 30 "-" "python-requests/2.9.1"
2016-07-19 12:54:00-0400 [-] "192.168.50.205" - - [19/Jul/2016:16:53:55 +0000] "GET /test/ HTTP/1.1" 200 30 "-" "python-requests/2.9.1"
2016-07-19 12:54:05-0400 [-] "192.168.50.205" - - [19/Jul/2016:16:54:00 +0000] "GET /test/ HTTP/1.1" 200 30 "-" "python-requests/2.9.1"
如您所见,服务器正在阻止当前的执行,它似乎是以同步而非异步的方式工作。在
我错过了什么?在
谨致问候。在
你错过了很多关于扭曲的重要概念。关于同步行为,你是绝对正确的,如果你不显式地使用异步函数(即^{} ),Klein的行为类似于同步框架,比如烧瓶或瓶子。在您的例子中,您没有使用任何异步功能,所以代码是按顺序执行的。查看https://github.com/notoriousno/klein-basics/blob/intro/nonblocking.rst这将有助于您理解Klein和Twisted中异步的基础知识。提醒读者延迟不会让代码神奇地异步!您必须仔细设计以实现并发执行。在
使代码异步
让我们尝试修复您的代码,使它异步运行。我将分几节复习这些概念。如果需要更多信息,请发表意见,我会处理的。让我们从所需的导入开始:
设置标题()
下一步,我们来改变
^{pr2}$setHeader()
函数。request.setHeader
函数的速度相当快,因此可以多次运行而无需严重阻塞。因此,可以使用一个函数来生成一个带有回调的Deferred
对象,该对象将设置各种头密钥/值对:在不详细介绍的情况下,我们使用
Deferred.addCallback()
将回调链接在一起。在本例中,回调函数是local_setHeader()
,它只是设置头。最后,函数将返回Deferred
。如果您注意到,_setHeader()
接受一个参数previous_result
,我们暂时忽略它们。在清除参数()
如果使用循环(
for
或while
),通常最好使用inlineCallbacks
来yield
结果。使用此方法可以在不阻塞主ioloop的情况下以同步的方式运行东西。在这是一个不好的例子,但是它应该说明如何使用}。我想演示多种异步样式。在
yield
来等待一个值。作为补充说明,setHeader()
函数也可以使用inlineCallbacks
和{克莱恩路线
最后,让我们实际使用路由中的异步函数:
别吓坏了!首先我们调用}的结果,并将时间戳写入响应体。在
cleanParams()
,它返回一个Deferred
,当它完成时,returnValue
将被写入响应体。接下来,将通过我们的setHeader()
设置头,它显式返回一个Deferred
。你在使用time.sleep(5)
,你无意中阻塞了整个反应堆回路。在Klein/Twisted中,如果以后想做某事,通常会使用callLater()
。最后,我们通过gatherResults()
等待延迟asyncClean
和{最终代码
服务器.py
测试.sh
相关问题 更多 >
编程相关推荐