diff options
author | Richard van der Hoff <richard@matrix.org> | 2018-09-18 19:02:45 +0100 |
---|---|---|
committer | Richard van der Hoff <richard@matrix.org> | 2018-09-18 19:02:45 +0100 |
commit | 38ead946a9571f1916228c3d96aad48b6b57ef89 (patch) | |
tree | cdc68014a0368b266796c83f78b9a02e41c0fe07 /synapse/util/async_helpers.py | |
parent | towncrier (diff) | |
parent | Merge pull request #3879 from matrix-org/matthew/fix-autojoin (diff) | |
download | synapse-38ead946a9571f1916228c3d96aad48b6b57ef89.tar.xz |
Merge remote-tracking branch 'origin/develop' into neilj/fix_room_invite_mail_links
Diffstat (limited to 'synapse/util/async_helpers.py')
-rw-r--r-- | synapse/util/async_helpers.py | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/synapse/util/async_helpers.py b/synapse/util/async_helpers.py index 9b3f2f4b96..40c2946129 100644 --- a/synapse/util/async_helpers.py +++ b/synapse/util/async_helpers.py @@ -438,3 +438,55 @@ 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 + + if not new_d.called: + new_d.errback(DeferredTimeoutError(timeout, "Deferred")) + + deferred.cancel() + + 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 |