Python Klein - 非阻塞 API
Python Klein - Non Blocking API
需要 Klein API 的非阻塞帮助。
这是一个简单的测试应用程序:
# -*- coding: utf-8 -*-
import datetime
import json
import time
from klein import Klein
app = Klein()
async def delay(seconds):
"""Set some delay for test"""
time.sleep(seconds)
return "Works"
@app.route('/', branch=True)
async def main(request):
some_data = await delay(5)
return json.dumps([{
"status": "200",
"time": datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
"data": some_data
}])
app.run("localhost", 8080)
然后只需 运行 我的 server.py
然后同时向 http://127.0.0.1:8080/
发送 2 个请求。
结果是:
[ { "status": "200", "time": "2019-10-18 20:57:16", "data": "Works" } ]
[ { "status": "200", "time": "2019-10-18 20:57:21", "data": "Works" } ]
每次响应之间延迟 5 秒。
问题:
如何使此代码同时处理 2 个请求,现在它正在一个接一个地处理...
也试过用twistd,结果一样
PYTHONPATH=. twistd --pidfile=apserver.pid -n web --class=api.resource --port tcp:8000:interface=0.0.0.0
谢谢
所以,问题是您的 delay
函数 - 它是一个阻塞函数,因为 python 的 time.sleep
- 正在阻塞。更多相关信息,您可以阅读 .
你应该使用task.deferLater
which you can think of as the non-blocking sleep function of Twisted framework, similar to asyncio.sleep()
# app.py
import datetime
import json
import treq
from klein import Klein
from twisted.internet import task, reactor
app = Klein()
async def delay1(secs):
await task.deferLater(reactor, secs)
return "Works"
def delay2(secs):
return task.deferLater(reactor, secs, lambda: "Works")
@app.route('/', branch=True)
async def main(request):
some_data = await delay1(5) # or some_data = await delay2(5)
return json.dumps([{
"status": "200",
"time": datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
"data": some_data
}])
def send_requests():
for i in range(2):
print("request", datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
d = treq.get('http://localhost:8080')
d.addCallback(treq.content)
d.addCallback(lambda x: print("response", x.decode()))
# send 2 concurrent requests every 10 seconds to test the code
repeating = task.LoopingCall(send_requests)
repeating.start(10, now=False)
app.run("localhost", 8080)
到运行代码
$ pip3 install treq klein
$ python3 app.py
等待 10 秒,输出应该是
2019-10-21 17:17:11-0400 [-] request 2019-10-21 17:17:11
2019-10-21 17:17:11-0400 [-] request 2019-10-21 17:17:11
2019-10-21 17:17:16-0400 [-] "127.0.0.1" - - [21/Oct/2019:21:17:16 +0000] "GET / HTTP/1.1" 200 67 "-" "-"
2019-10-21 17:17:16-0400 [-] "127.0.0.1" - - [21/Oct/2019:21:17:16 +0000] "GET / HTTP/1.1" 200 67 "-" "-"
2019-10-21 17:17:16-0400 [-] response [{"status": "200", "time": "2019-10-21 17:17:16", "data": "Works"}]
2019-10-21 17:17:16-0400 [-] response [{"status": "200", "time": "2019-10-21 17:17:16", "data": "Works"}]
需要 Klein API 的非阻塞帮助。 这是一个简单的测试应用程序:
# -*- coding: utf-8 -*-
import datetime
import json
import time
from klein import Klein
app = Klein()
async def delay(seconds):
"""Set some delay for test"""
time.sleep(seconds)
return "Works"
@app.route('/', branch=True)
async def main(request):
some_data = await delay(5)
return json.dumps([{
"status": "200",
"time": datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
"data": some_data
}])
app.run("localhost", 8080)
然后只需 运行 我的 server.py
然后同时向 http://127.0.0.1:8080/
发送 2 个请求。
结果是:
[ { "status": "200", "time": "2019-10-18 20:57:16", "data": "Works" } ]
[ { "status": "200", "time": "2019-10-18 20:57:21", "data": "Works" } ]
每次响应之间延迟 5 秒。
问题:
如何使此代码同时处理 2 个请求,现在它正在一个接一个地处理...
也试过用twistd,结果一样
PYTHONPATH=. twistd --pidfile=apserver.pid -n web --class=api.resource --port tcp:8000:interface=0.0.0.0
谢谢
所以,问题是您的 delay
函数 - 它是一个阻塞函数,因为 python 的 time.sleep
- 正在阻塞。更多相关信息,您可以阅读
你应该使用task.deferLater
which you can think of as the non-blocking sleep function of Twisted framework, similar to asyncio.sleep()
# app.py
import datetime
import json
import treq
from klein import Klein
from twisted.internet import task, reactor
app = Klein()
async def delay1(secs):
await task.deferLater(reactor, secs)
return "Works"
def delay2(secs):
return task.deferLater(reactor, secs, lambda: "Works")
@app.route('/', branch=True)
async def main(request):
some_data = await delay1(5) # or some_data = await delay2(5)
return json.dumps([{
"status": "200",
"time": datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
"data": some_data
}])
def send_requests():
for i in range(2):
print("request", datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
d = treq.get('http://localhost:8080')
d.addCallback(treq.content)
d.addCallback(lambda x: print("response", x.decode()))
# send 2 concurrent requests every 10 seconds to test the code
repeating = task.LoopingCall(send_requests)
repeating.start(10, now=False)
app.run("localhost", 8080)
到运行代码
$ pip3 install treq klein
$ python3 app.py
等待 10 秒,输出应该是
2019-10-21 17:17:11-0400 [-] request 2019-10-21 17:17:11
2019-10-21 17:17:11-0400 [-] request 2019-10-21 17:17:11
2019-10-21 17:17:16-0400 [-] "127.0.0.1" - - [21/Oct/2019:21:17:16 +0000] "GET / HTTP/1.1" 200 67 "-" "-"
2019-10-21 17:17:16-0400 [-] "127.0.0.1" - - [21/Oct/2019:21:17:16 +0000] "GET / HTTP/1.1" 200 67 "-" "-"
2019-10-21 17:17:16-0400 [-] response [{"status": "200", "time": "2019-10-21 17:17:16", "data": "Works"}]
2019-10-21 17:17:16-0400 [-] response [{"status": "200", "time": "2019-10-21 17:17:16", "data": "Works"}]