Get rid of DeferredList.

This commit is contained in:
Itamar Turner-Trauring 2023-02-23 10:07:57 -05:00
parent 32768e310a
commit 74e77685a3

View File

@ -942,18 +942,31 @@ async def _pick_a_http_server(
) -> DecodedURL: ) -> DecodedURL:
"""Pick the first server we successfully send a request to.""" """Pick the first server we successfully send a request to."""
while True: while True:
result = await defer.DeferredList([ result : defer.Deferred[Union[DecodedURL, None]] = defer.Deferred()
request(reactor, nurl) for nurl in nurls
], consumeErrors=True, fireOnOneCallback=True) def succeeded(nurl: DecodedURL, result=result):
# Apparently DeferredList is an awful awful API. If everything fails, # Only need the first successful NURL:
# you get back a list of (False, Failure), if it succeeds, you get a if result.called:
# tuple of (value, index). return
if isinstance(result, list): result.callback(nurl)
def failed(failure, failures=[], result=result):
log.err(failure)
failures.append(None)
if len(failures) == len(nurls):
# All our potential NURLs failed...
result.callback(None)
for index, nurl in enumerate(nurls):
request(reactor, nurl).addCallback(
lambda _, nurl=nurl: nurl).addCallbacks(succeeded, failed)
first_nurl = await result
if first_nurl is None:
# Failed to connect to any of the NURLs:
await deferLater(reactor, 1, lambda: None) await deferLater(reactor, 1, lambda: None)
else: else:
assert isinstance(result, tuple) return first_nurl
_, index = result
return nurls[index]
@implementer(IServer) @implementer(IServer)