Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/276.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/python-2.7/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何限制请求执行时间?_Python_Python 2.7_Google App Engine_Task - Fatal编程技术网

Python 如何限制请求执行时间?

Python 如何限制请求执行时间?,python,python-2.7,google-app-engine,task,Python,Python 2.7,Google App Engine,Task,我应该在3秒钟内给你答复 我的处理程序与第三方服务器进行对话,第三方服务器可能在3秒钟内回复,也可能无法回复 我想到了以下代码- class MainReply(webapp2.RequestHandler): def get(self): # do something # start task to talk with 3rd server for i in range(300): # wait 3 seconds

我应该在3秒钟内给你答复

我的处理程序与第三方服务器进行对话,第三方服务器可能在3秒钟内回复,也可能无法回复

我想到了以下代码-

class MainReply(webapp2.RequestHandler):
    def get(self):
        # do something
        # start task to talk with 3rd server
        for i in range(300): # wait 3 seconds
            # check task status
            # if finished, then break
            time.sleep(0.01)
        # if not finished, inform user
这是正确的方法吗?还是有更好的解决方案


Upd。我正在开发语音助手机器人(类似于谷歌助手),机器人必须在3秒内回复。而且一旦请求完成,机器人就不能自己启动应答,即我不能再给出另一个应答。由于这是语音助手,我不能给出链接。我在考虑下面的方法——如果我能在3秒钟内给出一个正常的答案,那么就给出它。如果没有-请用户用简单的单词如“Status”再次询问。基本规则是,您永远不应该像您的帖子中所描述的那样创建池,因为(1)您“手动”阻止了超过需要的资源(2)您将代码弄乱,模拟实际不是的异步代码,(3)语言通常提供处理并发编程的工具,这是专门为这类任务设计的,而且这对您来说比您能够实现它要好得多(在大多数情况下)

按照你的要求。我写了一个可以测试的简单程序。检查
asyncio。等待
文档。还可以找到一些有关异步的有用指南

将代码复制到文件中并运行
$python[filename]

import asyncio
import random
from concurrent.futures._base import TimeoutError

async def safe_get():
    result = "I'm currently out of my office."
    try:
        result = await asyncio.wait_for(get(), 3)
    except TimeoutError as e:
        print("Responder thought too much about his answer")
    return result

async def get(a=1,b=6):
    random_time = random.randint(a,b)
    await asyncio.sleep(random_time)
    return "I'm doing good thanks! Sorry it took me " + str(random_time) + "s to answer."

async def main():
    # Toggle comment on the two following lines to see (1) unwanted behaviour and (2) wanted behaviour
    # response = await get()
    response = await safe_get()
    print(response)

if __name__ == "__main__":
    asyncio.run(main())


基本原则是,您永远不应该像您的帖子中所描述的那样使用池,因为(1)您“手动”阻塞了超过所需的资源(2)您将代码弄乱,模拟实际并非如此的异步代码,(3)语言通常提供处理并发编程的工具,这些工具专门用于此类任务,在大多数情况下,这比你能实现的要好得多

按照你的要求。我写了一个可以测试的简单程序。检查
asyncio。等待
文档。还可以找到一些有关异步的有用指南

将代码复制到文件中并运行
$python[filename]

import asyncio
import random
from concurrent.futures._base import TimeoutError

async def safe_get():
    result = "I'm currently out of my office."
    try:
        result = await asyncio.wait_for(get(), 3)
    except TimeoutError as e:
        print("Responder thought too much about his answer")
    return result

async def get(a=1,b=6):
    random_time = random.randint(a,b)
    await asyncio.sleep(random_time)
    return "I'm doing good thanks! Sorry it took me " + str(random_time) + "s to answer."

async def main():
    # Toggle comment on the two following lines to see (1) unwanted behaviour and (2) wanted behaviour
    # response = await get()
    response = await safe_get()
    print(response)

if __name__ == "__main__":
    asyncio.run(main())


除了有问题的用户体验(响应速度慢,可能不是用户正在等待的响应)之外,这种方法还会给服务器的完整性带来风险:对于每个挂起的请求,服务器都将使用资源,如果传入请求高峰,它可能会在其可用池或资源上运行(若有限制)或可能导致成本上升(例如,若配置为自动扩展,则启动额外实例以跟上其他传入请求)


一般来说,对于可能需要很长时间的请求,最好立即使用挂起请求的ID和补充URL进行答复,在这些URL中,客户端可以检查请求状态并最终获得预期的响应(如果可用)。您的服务器将在后台而不是在原始传入请求线程上处理get从第三方服务器获取答案。通过这种方式,您可以处理可能需要很长时间才能从第三方或内部处理获得答案的任何类型的请求。

除了有问题的用户体验-响应缓慢,可能不是用户等待的响应-这种方法会带来风险对于您的服务器的完整性:对于每个挂起的请求,您的服务器都将使用资源,并且在高传入请求峰值的情况下,它可能会运行在其可用池或资源上(如果有限),或者可能会推高您的成本(例如,如果配置为自动扩展,则启动其他实例以跟上其他传入请求)


一般来说,对于可能需要很长时间的请求,最好立即使用挂起请求的ID和补充URL进行答复,在这些URL中,客户端可以检查请求状态并最终获得预期的响应(如果可用)。您的服务器将在后台而不是在原始传入请求线程上处理get正在从第三方服务器获取答案。通过这种方式,您可以处理可能需要很长时间才能从第三方或内部处理获取答案的任何类型的请求。

您是否通过http与该第三方服务器通信?您是否可以在python请求中使用
timeout
参数

class MainReply(webapp2.RequestHandler):
    def get(self):
        # do something
        try:
            r = requests.post(... , timeout=3)
            # finished, inform user
        except requests.exceptions.Timeout:
            # not finished, inform user

您是否通过http与该第三方服务器进行通信?能否在python请求中使用
timeout
参数

class MainReply(webapp2.RequestHandler):
    def get(self):
        # do something
        try:
            r = requests.post(... , timeout=3)
            # finished, inform user
        except requests.exceptions.Timeout:
            # not finished, inform user

就编程基础而言,我认为这永远不会是一种方法。您应该搜索事件订阅和观察者模式,如果语言默认不提供,请检查是否可用。@MikeMajara,谢谢,但我认为它在我的情况下不起作用。假设我订阅了任务完成事件。但它可能在3点之前发生秒或之后。这有什么帮助?我只能在3秒钟内回答用户。你说只在3秒钟内回答用户是什么意思?如果答案在<3秒钟内存在:返回它;否则返回错误?否则-返回另一个答案。就编程基础而言,我会说这永远不会是一种方法。你应该搜索事件脚本,然后观察服务器模式,如果默认语言不提供,请检查是否可用。@MikeMajara,谢谢,但我认为它在我的情况下不起作用。假设我订阅了任务完成事件。但它可能发生在3秒钟之前或之后。这有什么帮助?我只能在3秒钟内回答用户。你说只在3秒钟内回答用户是什么意思?如果答案在<3s中:返回;否则返回错误?否则-返回另一个答案。谢谢,丹。让我告诉你更多细节-我正在开发语音助手机器人(类似于谷歌助手),机器人必须在3秒钟内回复。一旦请求完成,机器人自身无法启动应答,即我无法给出另一个应答。由于这是语音助手,我无法给出链接。我正在考虑以下方法-如果我能在3秒钟内给出正常应答