|
@@ -66,7 +66,7 @@ from synapse.http.client import (
|
|
|
)
|
|
|
from synapse.http.federation.matrix_federation_agent import MatrixFederationAgent
|
|
|
from synapse.logging import opentracing
|
|
|
-from synapse.logging.context import make_deferred_yieldable
|
|
|
+from synapse.logging.context import make_deferred_yieldable, run_in_background
|
|
|
from synapse.logging.opentracing import set_tag, start_active_span, tags
|
|
|
from synapse.types import JsonDict
|
|
|
from synapse.util import json_decoder
|
|
@@ -553,20 +553,29 @@ class MatrixFederationHttpClient:
|
|
|
with Measure(self.clock, "outbound_request"):
|
|
|
# we don't want all the fancy cookie and redirect handling
|
|
|
# that treq.request gives: just use the raw Agent.
|
|
|
- request_deferred = self.agent.request(
|
|
|
+
|
|
|
+ # To preserve the logging context, the timeout is treated
|
|
|
+ # in a similar way to `defer.gatherResults`:
|
|
|
+ # * Each logging context-preserving fork is wrapped in
|
|
|
+ # `run_in_background`. In this case there is only one,
|
|
|
+ # since the timeout fork is not logging-context aware.
|
|
|
+ # * The `Deferred` that joins the forks back together is
|
|
|
+ # wrapped in `make_deferred_yieldable` to restore the
|
|
|
+ # logging context regardless of the path taken.
|
|
|
+ request_deferred = run_in_background(
|
|
|
+ self.agent.request,
|
|
|
method_bytes,
|
|
|
url_bytes,
|
|
|
headers=Headers(headers_dict),
|
|
|
bodyProducer=producer,
|
|
|
)
|
|
|
-
|
|
|
request_deferred = timeout_deferred(
|
|
|
request_deferred,
|
|
|
timeout=_sec_timeout,
|
|
|
reactor=self.reactor,
|
|
|
)
|
|
|
|
|
|
- response = await request_deferred
|
|
|
+ response = await make_deferred_yieldable(request_deferred)
|
|
|
except DNSLookupError as e:
|
|
|
raise RequestSendFailed(e, can_retry=retry_on_dns_fail) from e
|
|
|
except Exception as e:
|