美文网首页
如何为自己的函数或接口实现Timeout超时监听(Python)

如何为自己的函数或接口实现Timeout超时监听(Python)

作者: 越大大雨天 | 来源:发表于2020-03-07 16:06 被阅读0次

背景

需求背景:
最近收到一个需求,需要为某个接口实现超时检测功能。由于计算量和服务问题,该接口调用返回的时间可能出现过长的情况。需求方希望设定一个超时参数,当函数调用时间超时则返回一个超时的json数据,未超时则正常返回数据。

最终我使用了多线程 + 队列Queue对需求进行了实现,故总结一下本次实现的方法和思路。

原始代码模拟

使用如下代码最简单地还原一下原始接口情景,该代码下,调用task()方法可能存在随机的5~20秒延时才能返回:

import time
import random


# 该接口调用时间可能为5秒到20秒,希望能有一个接口超时检测功能。
# 若延迟在10秒内,则返回正常信息;若延迟大于10秒,则立即返回一个超时的信息。
def task():
    print("start task...")
    start = time.time()
    # 模拟任务随机耗时
    time.sleep(random.randint(5, 20))
    end = time.time()
    print("该次接口调用耗时:{}s".format(end-start))
    return {"status": "succeed"}


if __name__ == '__main__':
    result = task()
    print("返回结果为:{}".format(result))

结果示例,返回结果的时间可能小于10秒也可能大于十秒:

# 结果1
start task...
该次接口调用耗时:16.003031253814697s
返回结果为:{'status': 'succeed'}

# 结果2
start task...
该次接口调用耗时:7.378031253887643s
返回结果为:{'status': 'succeed'}

代码改造,超时监听

在主函数中,实例化一个队列并开启一个多线程任务,使用额外线程运行原有函数中的耗时代码部分,并将最终结果添加到主函数中的队列中。在主线程内,使用get阻塞获取队列中的结果,并传入超时参数,若在超时限制内获取到了结果,则正常返回;若触发了超时异常,则返回超时结果。无论怎样,主线程都将在规定Timeout内进行返回。

代码示例如下:

# 将耗时部分抽离为单独的函数,并接受一个队列参数,该队列为主函数中实例化的队列对象,将最终结果put到该队列中
def time_consuming_code(q):
    start = time.time()
    time.sleep(random.randint(5, 20))
    res = {"status": "succeed"}
    q.put(res)
    end = time.time()
    print("耗时部分后台线程耗时:{}".format(end-start))
    

def task(timeout=10):
    print("start task...")
    start = time.time()
    # 实例化一个队列
    q = Queue()
    # 开启新线程运行耗时部分代码
    t = Thread(target=time_consuming_code, args=(q,))
    # 开启主线程守护,主线程结束则关闭子线程
    t.daemon = True
    t.start()
    # 阻塞超时时间获取队列中的结果,若时间限制内未获取,则捕获异常,返回超时json信息
    try:
        res = q.get(timeout=timeout)
    except Empty:
        res = {"status": "timeout"}
    end = time.time()
    print("该次接口调用耗时:{}s".format(end - start))
    return res


if __name__ == '__main__':
    result = task()
    print("返回结果为:{}".format(result))

输出示例:
主接口耗时最多只会是10秒:

# 正常返回结果:
start task...
耗时部分后台线程耗时:8.000471115112305
该次接口调用耗时:8.000840902328491s
返回结果为:{'status': 'succeed'}

#超时返回结果,超时后耗时任务的子线程被强制关闭,因此看不到子线程耗时输出:
start task...
该次接口调用耗时:10.005242109298706s
返回结果为:{'status': 'timeout'}

总结

以上便是该次利用队列的阻塞获取+多线程实现的超时检测代码demo,你可以将timeout参数单独剥离为配置设置,控制超时设定。
希望能对看了文章的你提供思路。

相关文章

  • 如何为自己的函数或接口实现Timeout超时监听(Python)

    背景 需求背景:最近收到一个需求,需要为某个接口实现超时检测功能。由于计算量和服务问题,该接口调用返回的时间可能出...

  • Android Java变道Kotlin(1)

    1.监听函数 函数式 函数作为变量 内部类实现View.OnClickListener接口

  • Okio 超时机制

    Okio中有同步超时和异步超时。 同步超时Timeout类 Timeout类提供了两个互补的控制机制来定义超时策略...

  • 1- 设计模式

    接口的实现1:定义一个类Payment,让后面的函数继承这个类。 具体实现由后续的函数去实现。缺点:接口再函数,如...

  • requests timeout无效,加上setdefaultt

    在requests里,可以通过timeout参数 设置请求超时时间,超时则抛出异常 timeout=(10,30)...

  • nginx返回504排查思路

    nginx返回504一般代表gateway timeout,也就是接口请求超时。 相关参数 NGINX 涉及到请求...

  • Android ANR 定位与分析

    ANR的分类 KeyDispatch Timeout :按键或触摸事件在特定时间内无响应。超时时间5秒。超时时间是...

  • Hystrix - 基于 timeout 机制为服务接口调用超时

    基于 timeout 机制为服务接口调用超时提供安全保护 一般来说,在调用依赖服务的接口的时候,比较常见的一个问题...

  • 发包程序小记

    1、说说发包程序里面的timeout 设置因为socket receive函数,如果没有设置超时时间就会按照默认时...

  • Promise

    实现如下函数 function sleep(timeout: number): Promise { throw n...

网友评论

      本文标题:如何为自己的函数或接口实现Timeout超时监听(Python)

      本文链接:https://www.haomeiwen.com/subject/szecdhtx.html