diff options
author | Erik Johnston <erikj@jki.re> | 2018-09-14 19:56:11 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-09-14 19:56:11 +0100 |
commit | c30cfff5723a123d9abd5c86300d278882dcb385 (patch) | |
tree | 47f652b55ca626f0027bb827bc99faf38f7188e7 /synapse/util | |
parent | don't filter membership events based on history visibility (#3874) (diff) | |
parent | Newsfile (diff) | |
download | synapse-c30cfff5723a123d9abd5c86300d278882dcb385.tar.xz |
Merge pull request #3875 from matrix-org/erikj/extra_timeouts
Add an awful secondary timeout to fix wedged requests
Diffstat (limited to 'synapse/util')
-rw-r--r-- | synapse/util/async_helpers.py | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/synapse/util/async_helpers.py b/synapse/util/async_helpers.py index 9b3f2f4b96..083e4f4128 100644 --- a/synapse/util/async_helpers.py +++ b/synapse/util/async_helpers.py @@ -438,3 +438,54 @@ def _cancelled_to_timed_out_error(value, timeout): value.trap(CancelledError) raise DeferredTimeoutError(timeout, "Deferred") return value + + +def timeout_no_seriously(deferred, timeout, reactor): + """The in build twisted deferred addTimeout (and the method above) + completely fail to time things out under some unknown circumstances. + + Lets try a different way of timing things out and maybe that will make + things work?! + + TODO: Kill this with fire. + """ + + new_d = defer.Deferred() + + timed_out = [False] + + def time_it_out(): + timed_out[0] = True + deferred.cancel() + + if not new_d.called: + new_d.errback(DeferredTimeoutError(timeout, "Deferred")) + + delayed_call = reactor.callLater(timeout, time_it_out) + + def convert_cancelled(value): + if timed_out[0]: + return _cancelled_to_timed_out_error(value, timeout) + return value + + deferred.addBoth(convert_cancelled) + + def cancel_timeout(result): + # stop the pending call to cancel the deferred if it's been fired + if delayed_call.active(): + delayed_call.cancel() + return result + + deferred.addBoth(cancel_timeout) + + def success_cb(val): + if not new_d.called: + new_d.callback(val) + + def failure_cb(val): + if not new_d.called: + new_d.errback(val) + + deferred.addCallbacks(success_cb, failure_cb) + + return new_d |