From 7f9f89f24d1ab379a1a947759fae58181c88fc06 Mon Sep 17 00:00:00 2001 From: halfcrazy Date: Thu, 2 Jul 2015 13:19:54 +0800 Subject: [PATCH] implement accurate timeout function --- slack_bot/app.py | 9 +++++++-- slack_bot/plugins/github_issue.py | 9 +++++---- slack_bot/utils.py | 12 +++++++++--- 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/slack_bot/app.py b/slack_bot/app.py index 29ce785..65e12ac 100644 --- a/slack_bot/app.py +++ b/slack_bot/app.py @@ -1,8 +1,9 @@ # coding=utf-8 +import time import os import re -from flask import Flask +from flask import Flask, g from flask_slackbot import SlackBot @@ -37,10 +38,14 @@ def create_app(config=None): slackbot.set_handler(callback) slackbot.filter_outgoing(_filter) + @app.before_request + def start_time_it(): + g.time = time.time() + return app -@timeout(30.0) +@timeout(g, 30.0) def callback(kwargs): s = convert2str(kwargs['text']) trigger_word = convert2str(kwargs['trigger_word']) diff --git a/slack_bot/plugins/github_issue.py b/slack_bot/plugins/github_issue.py index 5b29ced..e4207de 100644 --- a/slack_bot/plugins/github_issue.py +++ b/slack_bot/plugins/github_issue.py @@ -37,7 +37,8 @@ def handle(data): if __name__ == '__main__': - from flask import Flask - app = Flask(__name__) - app.config['org_name'] = 'python-cn' - print handle(None) + # from flask import Flask + # app = Flask(__name__) + # app.config['org_name'] = 'python-cn' + # print handle(None) + pass diff --git a/slack_bot/utils.py b/slack_bot/utils.py index 0927df6..7c67cc2 100644 --- a/slack_bot/utils.py +++ b/slack_bot/utils.py @@ -1,19 +1,25 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- +import time from multiprocessing import TimeoutError from multiprocessing.pool import ThreadPool from functools import wraps -def timeout(seconds): +def timeout(g, seconds, default="timeout"): def decorator(fn): @wraps(fn) def wrapper(*args, **kwargs): pool = ThreadPool(processes=1) async_result = pool.apply_async(fn, args=args, kwds=kwargs) try: - return async_result.get(seconds) + # the time cost before start fn + cost_time = time.time() - g.time + return async_result.get(seconds - cost_time) except TimeoutError: - return kwargs.pop('default', {'text': 'timeout'}) + return default() if callable(default) else default + finally: + pool.close() + pool.terminate() return wrapper return decorator