Python Klein-非阻塞API

问题描述 投票:0回答:1

需要有关Klein API的无阻塞帮助这是简单的测试应用程序:

# -*- coding: utf-8 -*-
from klein import Klein
import json
import time
import datetime

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”,“数据”:“作品”}]

[{“ status”:“ 200”,“ time”:“ 2019-10-18 20:57:21”,“数据”:“作品”}]

每个响应之间延迟5秒。

问题:

如何使此代码同时处理两个请求,现在可以一个接一个地工作...

也尝试使用扭曲,结果相同

PYTHONPATH =。扭曲--pidfile = apserver.pid -n web --class = api.resource --port tcp:8000:interface = 0.0.0.0

谢谢

python-3.x asynchronous twisted nonblocking klein-mvc
1个回答
0
投票

所以,问题出在您的delay函数-它是一个阻塞函数,因为python的time.sleep-正在阻塞。有关更多信息,您可以阅读here

您的问题的解决方案是使用task.deferLater,如下所示

task.deferLater

并且输出应该是

# -*- coding: utf-8 -*-
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 requests every 10 seconds
repeating = task.LoopingCall(send_requests)
repeating.start(10, now=False)

app.run("localhost", 8080)

© www.soinside.com 2019 - 2024. All rights reserved.