Merge pull request #4243 from moigagoo/devel
Stdlib: asyncdispatch: `all` proc: Add support of varargs, fix issues, add tests.
This commit is contained in:
commit
f440bb7064
2 changed files with 89 additions and 16 deletions
|
|
@ -355,27 +355,50 @@ proc `or`*[T, Y](fut1: Future[T], fut2: Future[Y]): Future[void] =
|
||||||
fut2.callback = cb
|
fut2.callback = cb
|
||||||
return retFuture
|
return retFuture
|
||||||
|
|
||||||
proc all*[A](futs: seq[Future[A]]): Future[seq[A]] =
|
proc all*[T](futs: varargs[Future[T]]): auto =
|
||||||
## Returns a future which will complete once all futures in ``futs``
|
## Returns a future which will complete once
|
||||||
## complete.
|
## all futures in ``futs`` complete.
|
||||||
##
|
##
|
||||||
## The resulting future will hold the values of all awaited futures,
|
## If the awaited futures are not ``Future[void]``, the returned future
|
||||||
## in the order they are passed.
|
## will hold the values of all awaited futures in a sequence.
|
||||||
|
##
|
||||||
|
## If the awaited futures *are* ``Future[void]``,
|
||||||
|
## this proc returns ``Future[void]``.
|
||||||
|
|
||||||
var
|
when T is void:
|
||||||
retFuture = newFuture[seq[A]]("asyncdispatch.all")
|
var
|
||||||
retValues = newSeq[A](len(futs))
|
retFuture = newFuture[void]("asyncdispatch.all")
|
||||||
completedFutures = 0
|
completedFutures = 0
|
||||||
|
|
||||||
for i, fut in futs:
|
let totalFutures = len(futs)
|
||||||
fut.callback = proc(f: Future[A]) =
|
|
||||||
retValues[i] = f.read()
|
|
||||||
inc(completedFutures)
|
|
||||||
|
|
||||||
if completedFutures == len(futs):
|
for fut in futs:
|
||||||
retFuture.complete(retValues)
|
fut.callback = proc(f: Future[T]) =
|
||||||
|
inc(completedFutures)
|
||||||
|
|
||||||
return retFuture
|
if completedFutures == totalFutures:
|
||||||
|
retFuture.complete()
|
||||||
|
|
||||||
|
return retFuture
|
||||||
|
|
||||||
|
else:
|
||||||
|
var
|
||||||
|
retFuture = newFuture[seq[T]]("asyncdispatch.all")
|
||||||
|
retValues = newSeq[T](len(futs))
|
||||||
|
completedFutures = 0
|
||||||
|
|
||||||
|
for i, fut in futs:
|
||||||
|
proc setCallback(i: int) =
|
||||||
|
fut.callback = proc(f: Future[T]) =
|
||||||
|
retValues[i] = f.read()
|
||||||
|
inc(completedFutures)
|
||||||
|
|
||||||
|
if completedFutures == len(retValues):
|
||||||
|
retFuture.complete(retValues)
|
||||||
|
|
||||||
|
setCallback(i)
|
||||||
|
|
||||||
|
return retFuture
|
||||||
|
|
||||||
type
|
type
|
||||||
PDispatcherBase = ref object of RootRef
|
PDispatcherBase = ref object of RootRef
|
||||||
|
|
|
||||||
50
tests/async/tasyncall.nim
Normal file
50
tests/async/tasyncall.nim
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
discard """
|
||||||
|
file: "tasyncall.nim"
|
||||||
|
exitcode: 0
|
||||||
|
"""
|
||||||
|
import times, sequtils
|
||||||
|
import asyncdispatch
|
||||||
|
|
||||||
|
const
|
||||||
|
taskCount = 10
|
||||||
|
sleepDuration = 500
|
||||||
|
|
||||||
|
proc futureWithValue(x: int): Future[int] {.async.} =
|
||||||
|
await sleepAsync(sleepDuration)
|
||||||
|
return x
|
||||||
|
|
||||||
|
proc futureWithoutValue() {.async.} =
|
||||||
|
await sleepAsync(1000)
|
||||||
|
|
||||||
|
proc testFuturesWithValue(x: int): seq[int] =
|
||||||
|
var tasks = newSeq[Future[int]](taskCount)
|
||||||
|
|
||||||
|
for i in 0..<taskCount:
|
||||||
|
tasks[i] = futureWithValue(x)
|
||||||
|
|
||||||
|
result = waitFor all(tasks)
|
||||||
|
|
||||||
|
proc testFuturesWithoutValues() =
|
||||||
|
var tasks = newSeq[Future[void]](taskCount)
|
||||||
|
|
||||||
|
for i in 0..<taskCount:
|
||||||
|
tasks[i] = futureWithoutValue()
|
||||||
|
|
||||||
|
waitFor all(tasks)
|
||||||
|
|
||||||
|
block:
|
||||||
|
let
|
||||||
|
startTime = cpuTime()
|
||||||
|
results = testFuturesWithValue(42)
|
||||||
|
expected = repeat(42, taskCount)
|
||||||
|
execTime = cpuTime() - startTime
|
||||||
|
|
||||||
|
doAssert execTime * 1000 < taskCount * sleepDuration
|
||||||
|
doAssert results == expected
|
||||||
|
|
||||||
|
block:
|
||||||
|
let startTime = cpuTime()
|
||||||
|
testFuturesWithoutValues()
|
||||||
|
let execTime = cpuTime() - startTime
|
||||||
|
|
||||||
|
doAssert execTime * 1000 < taskCount * sleepDuration
|
||||||
Loading…
Add table
Add a link
Reference in a new issue