Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a simple API for getting the first available result from a sequence of Deferreds #11817

Closed
exarkun opened this issue Feb 28, 2023 · 0 comments · Fixed by #11818
Closed

Add a simple API for getting the first available result from a sequence of Deferreds #11817

exarkun opened this issue Feb 28, 2023 · 0 comments · Fixed by #11818

Comments

@exarkun
Copy link
Member

exarkun commented Feb 28, 2023

It is common to want to try a few things concurrently but only care about whichever of them completes successfully first.

One example of when this kind of thing is useful is when implementing "happy eyeballs". You want to let N operations run concurrently (some of them might just start with a delay). As soon as any one finishes you want to use its result and you have no use for any of the other results.

DeferredList(deferredList, fireOnOnecallback=True) is a little bit like this API except:

  • It is class-based which encourages the misunderstanding that subclassing Deferred is a good idea.
  • It mixes around 8 different APIs together in one, controlled by a confusing mix of flags.
  • It doesn't cancel the Deferreds that didn't finish first.

Describe the solution you'd like

An API dedicated to this use-case might look something like:

X = TypeVar("X")
Y = TypeVar("Y")
def race(ds: Sequence[Deferred[X]]) -> Deferred[tuple[int, X]]:
    """
    Select the first available result from the sequence of Deferreds and
    cancel the rest.

    :return: A cancellable ``Deferred`` that fires with the index and output
        of the element of ``ds`` to first have a success result, or that fires
        with a failure holding a list of their failures if they all fail.
    """
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant