summary refs log tree commit diff
path: root/synapse/rest/client/transactions.py
diff options
context:
space:
mode:
authorErik Johnston <erik@matrix.org>2018-05-23 10:54:14 +0100
committerErik Johnston <erik@matrix.org>2018-05-23 10:54:14 +0100
commit6e11803ed3669fb897fe61da168eb033ad495198 (patch)
tree936c98227c65d687318c3d573a4c4a5a5fdb1e33 /synapse/rest/client/transactions.py
parentMerge pull request #3226 from matrix-org/erikj/chunk_base (diff)
parentMerge pull request #3265 from matrix-org/erikj/limit_pagination (diff)
downloadsynapse-6e11803ed3669fb897fe61da168eb033ad495198.tar.xz
Merge branch 'develop' of github.com:matrix-org/synapse into erikj/room_chunks
Diffstat (limited to 'synapse/rest/client/transactions.py')
-rw-r--r--synapse/rest/client/transactions.py42
1 files changed, 21 insertions, 21 deletions
diff --git a/synapse/rest/client/transactions.py b/synapse/rest/client/transactions.py

index fceca2edeb..20fa6678ef 100644 --- a/synapse/rest/client/transactions.py +++ b/synapse/rest/client/transactions.py
@@ -19,6 +19,7 @@ import logging from synapse.api.auth import get_access_token_from_request from synapse.util.async import ObservableDeferred +from synapse.util.logcontext import make_deferred_yieldable, run_in_background logger = logging.getLogger(__name__) @@ -80,27 +81,26 @@ class HttpTransactionCache(object): Returns: Deferred which resolves to a tuple of (response_code, response_dict). """ - try: - return self.transactions[txn_key][0].observe() - except (KeyError, IndexError): - pass # execute the function instead. - - deferred = fn(*args, **kwargs) - - # if the request fails with a Twisted failure, remove it - # from the transaction map. This is done to ensure that we don't - # cache transient errors like rate-limiting errors, etc. - def remove_from_map(err): - self.transactions.pop(txn_key, None) - return err - deferred.addErrback(remove_from_map) - - # We don't add any other errbacks to the raw deferred, so we ask - # ObservableDeferred to swallow the error. This is fine as the error will - # still be reported to the observers. - observable = ObservableDeferred(deferred, consumeErrors=True) - self.transactions[txn_key] = (observable, self.clock.time_msec()) - return observable.observe() + if txn_key in self.transactions: + observable = self.transactions[txn_key][0] + else: + # execute the function instead. + deferred = run_in_background(fn, *args, **kwargs) + + observable = ObservableDeferred(deferred) + self.transactions[txn_key] = (observable, self.clock.time_msec()) + + # if the request fails with an exception, remove it + # from the transaction map. This is done to ensure that we don't + # cache transient errors like rate-limiting errors, etc. + def remove_from_map(err): + self.transactions.pop(txn_key, None) + # we deliberately do not propagate the error any further, as we + # expect the observers to have reported it. + + deferred.addErrback(remove_from_map) + + return make_deferred_yieldable(observable.observe()) def _cleanup(self): now = self.clock.time_msec()