Last active
October 18, 2020 09:28
-
-
Save fabiocerqueira/9fbeae90e41dc0cb73e46e44edede2c2 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from functools import wraps | |
from twisted.internet import defer, reactor | |
from twisted.python import failure | |
class DeferTimeoutError(Exception): | |
pass | |
def with_timeout(secs): | |
def inner(my_func): | |
@wraps(my_func) | |
def wrapper(*args, **kwargs): | |
def defer_cancel(d): | |
if not d.called: | |
d._suppressAlreadyCalled = True | |
d.errback( | |
failure.Failure( | |
DeferTimeoutError( | |
"{} timeout after {} secs".format(my_func.__name__, secs) | |
) | |
) | |
) | |
def completed(passthru): | |
if timeout_watcher.active(): | |
timeout_watcher.cancel() | |
return passthru | |
d = my_func(*args, **kwargs) | |
d._canceller = defer_cancel | |
timeout_watcher = reactor.callLater(secs, d.cancel) | |
d.addBoth(completed) | |
return d | |
return wrapper | |
return inner |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import time | |
import sys | |
from timeout_helper import DeferTimeoutError, with_timeout | |
from twisted.internet import defer, reactor | |
from twisted.web.client import Agent | |
# Example with_timeout usage | |
@defer.inlineCallbacks | |
def my_client_function(fake_delay): | |
agent = Agent(reactor, connectTimeout=5) | |
requester = with_timeout(secs=5)(agent.request) | |
response = yield requester( | |
"GET", "https://httpbin.org/delay/{}".format(fake_delay) | |
) | |
defer.returnValue(response.code) | |
@defer.inlineCallbacks | |
def main(delay): | |
start = time.time() | |
try: | |
result = yield my_client_function(delay) | |
print("status_code: {}".format(result)) | |
except DeferTimeoutError: | |
print("timedout :(") | |
end = time.time() | |
print("Exec time: {}s".format(end - start)) | |
reactor.stop() | |
if __name__ == "__main__": | |
if len(sys.argv) < 2: | |
print("Example: python usage.py 10") | |
sys.exit(1) | |
delay = sys.argv[1] | |
reactor.callLater(0, main, delay) | |
reactor.run() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
https://github.com/debian-python/txfixtures/blob/40d39a7e937ea499820c71b10e38fa5fbda099fa/txfixtures/_twisted/backports/defer.py - backport from 16.5 :D