Merge pull request #4243 from moigagoo/devel

Stdlib: asyncdispatch: `all` proc: Add support of varargs, fix issues, add tests.
This commit is contained in:
Dominik Picheta
2016-06-03 11:48:32 +01:00
2 changed files with 89 additions and 16 deletions

View File

@@ -355,27 +355,50 @@ proc `or`*[T, Y](fut1: Future[T], fut2: Future[Y]): Future[void] =
fut2.callback = cb
return retFuture
proc all*[A](futs: seq[Future[A]]): Future[seq[A]] =
## Returns a future which will complete once all futures in ``futs``
## complete.
proc all*[T](futs: varargs[Future[T]]): auto =
## Returns a future which will complete once
## all futures in ``futs`` complete.
##
## The resulting future will hold the values of all awaited futures,
## in the order they are passed.
## If the awaited futures are not ``Future[void]``, the returned future
## will hold the values of all awaited futures in a sequence.
##
## If the awaited futures *are* ``Future[void]``,
## this proc returns ``Future[void]``.
var
retFuture = newFuture[seq[A]]("asyncdispatch.all")
retValues = newSeq[A](len(futs))
completedFutures = 0
when T is void:
var
retFuture = newFuture[void]("asyncdispatch.all")
completedFutures = 0
for i, fut in futs:
fut.callback = proc(f: Future[A]) =
retValues[i] = f.read()
inc(completedFutures)
let totalFutures = len(futs)
if completedFutures == len(futs):
retFuture.complete(retValues)
for fut in futs:
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
PDispatcherBase = ref object of RootRef

50
tests/async/tasyncall.nim Normal file
View 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