mirror of
https://github.com/logos-storage/nim-chronos.git
synced 2026-01-06 07:23:08 +00:00
Fix issue with allFinished(), allFutures(), one() behavior when Futures passed are already finished. (#89)
Added test.
This commit is contained in:
parent
cbd8e03823
commit
4e2810cfe0
@ -693,10 +693,13 @@ proc allFutures*[T](futs: varargs[Future[T]]): Future[void] =
|
||||
nfuts[i].removeCallback(cb)
|
||||
|
||||
for fut in nfuts:
|
||||
fut.addCallback(cb)
|
||||
if not(fut.finished()):
|
||||
fut.addCallback(cb)
|
||||
else:
|
||||
inc(completedFutures)
|
||||
|
||||
retFuture.cancelCallback = cancellation
|
||||
if len(nfuts) == 0:
|
||||
if len(nfuts) == 0 or len(nfuts) == completedFutures:
|
||||
retFuture.complete()
|
||||
|
||||
return retFuture
|
||||
@ -730,10 +733,13 @@ proc allFinished*[T](futs: varargs[Future[T]]): Future[seq[Future[T]]] =
|
||||
fut.removeCallback(cb)
|
||||
|
||||
for fut in nfuts:
|
||||
fut.addCallback(cb)
|
||||
if not(fut.finished()):
|
||||
fut.addCallback(cb)
|
||||
else:
|
||||
inc(completedFutures)
|
||||
|
||||
retFuture.cancelCallback = cancellation
|
||||
if len(nfuts) == 0:
|
||||
if len(nfuts) == 0 or len(nfuts) == completedFutures:
|
||||
retFuture.complete(nfuts)
|
||||
|
||||
return retFuture
|
||||
@ -744,7 +750,7 @@ proc one*[T](futs: varargs[Future[T]]): Future[Future[T]] =
|
||||
##
|
||||
## If the argument is empty, the returned future FAILS immediately.
|
||||
##
|
||||
## On success returned Future will hold index in ``futs`` array.
|
||||
## On success returned Future will hold finished Future[T].
|
||||
##
|
||||
## On cancel futures in ``futs`` WILL NOT BE cancelled.
|
||||
var retFuture = newFuture[Future[T]]("chronos.one()")
|
||||
@ -769,6 +775,12 @@ proc one*[T](futs: varargs[Future[T]]): Future[Future[T]] =
|
||||
if not(nfuts[i].finished()):
|
||||
nfuts[i].removeCallback(cb)
|
||||
|
||||
# If one of the Future[T] already finished we return it as result
|
||||
for fut in nfuts:
|
||||
if fut.finished():
|
||||
retFuture.complete(fut)
|
||||
return retFuture
|
||||
|
||||
for fut in nfuts:
|
||||
fut.addCallback(cb)
|
||||
|
||||
|
||||
@ -520,6 +520,21 @@ suite "Future[T] behavior test suite":
|
||||
# 10 * 10 completed futures = 100
|
||||
result += completedFutures
|
||||
|
||||
proc testAllCompleted(operation: int): bool =
|
||||
proc client1(): Future[int] {.async.} =
|
||||
result = 1
|
||||
|
||||
proc client2(): Future[int] {.async.} =
|
||||
if true:
|
||||
raise newException(ValueError, "")
|
||||
|
||||
if operation == 1:
|
||||
var fut = allFutures(client1(), client2())
|
||||
result = fut.finished() and not(fut.failed())
|
||||
elif operation == 2:
|
||||
var fut = allFinished(client1(), client2())
|
||||
result = fut.finished() and not(fut.failed()) and (len(fut.read()) == 2)
|
||||
|
||||
proc testOneZero(): bool =
|
||||
var tseq = newSeq[Future[int]]()
|
||||
var fut = one(tseq)
|
||||
@ -645,6 +660,30 @@ suite "Future[T] behavior test suite":
|
||||
|
||||
result = true
|
||||
|
||||
proc testOneCompleted(): bool =
|
||||
proc client1(): Future[int] {.async.} =
|
||||
result = 1
|
||||
|
||||
proc client2(): Future[int] {.async.} =
|
||||
if true:
|
||||
raise newException(ValueError, "")
|
||||
|
||||
proc client3(): Future[int] {.async.} =
|
||||
await sleepAsync(100.milliseconds)
|
||||
result = 3
|
||||
|
||||
var f10 = client1()
|
||||
var f20 = client2()
|
||||
var f30 = client3()
|
||||
var fut1 = one(f30, f10, f20)
|
||||
var f11 = client1()
|
||||
var f21 = client2()
|
||||
var f31 = client3()
|
||||
var fut2 = one(f31, f21, f11)
|
||||
|
||||
result = fut1.finished() and not(fut1.failed()) and fut1.read() == f10 and
|
||||
fut2.finished() and not(fut2.failed()) and fut2.read() == f21
|
||||
|
||||
proc testCancelIter(): bool =
|
||||
var completed = 0
|
||||
|
||||
@ -854,6 +893,10 @@ suite "Future[T] behavior test suite":
|
||||
check testAllFuturesVarargs() == 30
|
||||
test "allFutures(varargs) test":
|
||||
check testAllFuturesSeq() == 300
|
||||
test "allFutures() already completed test":
|
||||
check testAllCompleted(1) == true
|
||||
test "allFinished() already completed test":
|
||||
check testAllCompleted(2) == true
|
||||
|
||||
test "one(zero) test":
|
||||
check testOneZero() == true
|
||||
@ -861,6 +904,8 @@ suite "Future[T] behavior test suite":
|
||||
check testOneVarargs() == true
|
||||
test "one(seq) test":
|
||||
check testOneSeq() == true
|
||||
test "one() already completed test":
|
||||
check testOneCompleted() == true
|
||||
|
||||
test "cancel() async procedure test":
|
||||
check testCancelIter() == true
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user