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

Operator `or` causes a future to be completed more than once #8982

Closed
k0zmo opened this issue Sep 16, 2018 · 0 comments

Comments

Projects
None yet
2 participants
@k0zmo
Copy link

commented Sep 16, 2018

Following code:

import asyncdispatch

proc failingAwaitable(p: int) {.async.} =
    await sleepAsync(500)
    if p > 0:
        raise newException(Exception, "exception")

proc main() {.async.} =
    let fut = failingAwaitable(1)
    try:
        await fut or sleepAsync(100)
        if fut.finished:
            echo "finished"
        else:
            echo "timeout"
    except:
        echo "failed"

asyncCheck main()
runForever()

uses operator or defined in here. When one of the future fails (like in above test case) the result future is complete twice - once using complete() and once using fail(). I propose following implementation of operator or:

proc `or`*[T, Y](fut1: Future[T], fut2: Future[Y]): Future[void] =
    ## Returns a future which will complete once either ``fut1`` or ``fut2``
    ## complete.
    var retFuture = newFuture[void]("asyncdispatch.`or`")
    proc cb[X](fut: Future[X]) =
      if not retFuture.finished:
        if fut.failed: retFuture.fail(fut.error)
        else: retFuture.complete()
    fut1.callback = cb[T]
    fut2.callback = cb[Y]
    return retFuture

@dom96 dom96 closed this in #9632 Nov 9, 2018

dom96 added a commit that referenced this issue Nov 9, 2018

complete future only once in `or` (fixes #8982) (#9632)
* complete future only once in `or`

Analogous to `and`.
Credits to @k0zmo for proposing the solution.

* add test
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.