From 33f053856611483f52dfaf07c062ca1e646d1083 Mon Sep 17 00:00:00 2001 From: Konstantin Molchanov Date: Tue, 31 May 2016 10:21:21 +0400 Subject: [PATCH 01/10] Stdlib: asyncdispatch: Add support of varargs to `all`. --- lib/pure/asyncdispatch.nim | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/pure/asyncdispatch.nim b/lib/pure/asyncdispatch.nim index 2c7aaf2bfa..69a290f597 100644 --- a/lib/pure/asyncdispatch.nim +++ b/lib/pure/asyncdispatch.nim @@ -377,6 +377,9 @@ proc all*[A](futs: seq[Future[A]]): Future[seq[A]] = return retFuture +proc all*[A](futs: varargs[Future[A]]): Future[seq[A]] = + return all(@futs) + type PDispatcherBase = ref object of RootRef timers: HeapQueue[tuple[finishAt: float, fut: Future[void]]] From fb9fa5f6a385d1861885b0481573e7dc97191d9f Mon Sep 17 00:00:00 2001 From: Konstantin Molchanov Date: Tue, 31 May 2016 14:51:24 +0400 Subject: [PATCH 02/10] Stdlib: asyncdispatch: `all` proc: Replace req with openarray. --- lib/pure/asyncdispatch.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/pure/asyncdispatch.nim b/lib/pure/asyncdispatch.nim index 69a290f597..de86cd5efb 100644 --- a/lib/pure/asyncdispatch.nim +++ b/lib/pure/asyncdispatch.nim @@ -355,7 +355,7 @@ 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]] = +proc all*[A](futs: openarray[Future[A]]): Future[seq[A]] = ## Returns a future which will complete once all futures in ``futs`` ## complete. ## From 5a007a84fc8350a3a43ddc712c7a59a9ab2dce79 Mon Sep 17 00:00:00 2001 From: Konstantin Molchanov Date: Tue, 31 May 2016 14:56:45 +0400 Subject: [PATCH 03/10] Stdlib: asyncdispatch: `all` proc: Fix incorect counter value issue. --- lib/pure/asyncdispatch.nim | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/lib/pure/asyncdispatch.nim b/lib/pure/asyncdispatch.nim index de86cd5efb..53c78d929b 100644 --- a/lib/pure/asyncdispatch.nim +++ b/lib/pure/asyncdispatch.nim @@ -368,12 +368,15 @@ proc all*[A](futs: openarray[Future[A]]): Future[seq[A]] = completedFutures = 0 for i, fut in futs: - fut.callback = proc(f: Future[A]) = - retValues[i] = f.read() - inc(completedFutures) + proc setCallback(i: int) = + fut.callback = proc(f: Future[A]) = + retValues[i] = f.read() + inc(completedFutures) - if completedFutures == len(futs): - retFuture.complete(retValues) + if completedFutures == len(retValues): + retFuture.complete(retValues) + + setCallback(i) return retFuture From 6e8053853ba58ffd21b562e2054f6604733a5142 Mon Sep 17 00:00:00 2001 From: Konstantin Molchanov Date: Tue, 31 May 2016 15:32:30 +0400 Subject: [PATCH 04/10] stdlib: asyncdispatch: `add` proc supports varargs now. --- lib/pure/asyncdispatch.nim | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/lib/pure/asyncdispatch.nim b/lib/pure/asyncdispatch.nim index 53c78d929b..2d34749a91 100644 --- a/lib/pure/asyncdispatch.nim +++ b/lib/pure/asyncdispatch.nim @@ -355,7 +355,7 @@ proc `or`*[T, Y](fut1: Future[T], fut2: Future[Y]): Future[void] = fut2.callback = cb return retFuture -proc all*[A](futs: openarray[Future[A]]): Future[seq[A]] = +proc all*[T](futs: varargs[Future[T]]): Future[seq[T]] = ## Returns a future which will complete once all futures in ``futs`` ## complete. ## @@ -364,12 +364,12 @@ proc all*[A](futs: openarray[Future[A]]): Future[seq[A]] = var retFuture = newFuture[seq[A]]("asyncdispatch.all") - retValues = newSeq[A](len(futs)) + retValues = newSeq[T](len(futs)) completedFutures = 0 for i, fut in futs: proc setCallback(i: int) = - fut.callback = proc(f: Future[A]) = + fut.callback = proc(f: Future[T]) = retValues[i] = f.read() inc(completedFutures) @@ -380,9 +380,6 @@ proc all*[A](futs: openarray[Future[A]]): Future[seq[A]] = return retFuture -proc all*[A](futs: varargs[Future[A]]): Future[seq[A]] = - return all(@futs) - type PDispatcherBase = ref object of RootRef timers: HeapQueue[tuple[finishAt: float, fut: Future[void]]] From c821cebf27a4ffa923580c5c034074eeb6547dca Mon Sep 17 00:00:00 2001 From: Konstantin Molchanov Date: Tue, 31 May 2016 15:33:41 +0400 Subject: [PATCH 05/10] stdlib: asyncdispatch: `all`: typo fixed. --- lib/pure/asyncdispatch.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/pure/asyncdispatch.nim b/lib/pure/asyncdispatch.nim index 2d34749a91..aa3fff581d 100644 --- a/lib/pure/asyncdispatch.nim +++ b/lib/pure/asyncdispatch.nim @@ -363,7 +363,7 @@ proc all*[T](futs: varargs[Future[T]]): Future[seq[T]] = ## in the order they are passed. var - retFuture = newFuture[seq[A]]("asyncdispatch.all") + retFuture = newFuture[seq[T]]("asyncdispatch.all") retValues = newSeq[T](len(futs)) completedFutures = 0 From f44e0653560ea180ea1d4200f358a641816cdf2b Mon Sep 17 00:00:00 2001 From: Konstantin Molchanov Date: Tue, 31 May 2016 22:33:51 +0400 Subject: [PATCH 06/10] sttdlib: asyncdispatch: `all`: Add Future[void] support. --- lib/pure/asyncdispatch.nim | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/lib/pure/asyncdispatch.nim b/lib/pure/asyncdispatch.nim index aa3fff581d..50349b1046 100644 --- a/lib/pure/asyncdispatch.nim +++ b/lib/pure/asyncdispatch.nim @@ -9,7 +9,7 @@ include "system/inclrtl" -import os, oids, tables, strutils, macros, times, heapqueue +import os, oids, tables, strutils, macros, times, heapqueue, sequtils import nativesockets, net, queues @@ -355,30 +355,34 @@ proc `or`*[T, Y](fut1: Future[T], fut2: Future[Y]): Future[void] = fut2.callback = cb return retFuture -proc all*[T](futs: varargs[Future[T]]): Future[seq[T]] = +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. - var - retFuture = newFuture[seq[T]]("asyncdispatch.all") - retValues = newSeq[T](len(futs)) - completedFutures = 0 + when T is void: + return foldl(futs, a and b) - for i, fut in futs: - proc setCallback(i: int) = - fut.callback = proc(f: Future[T]) = - retValues[i] = f.read() - inc(completedFutures) + else: + var + retFuture = newFuture[seq[T]]("asyncdispatch.all") + retValues = newSeq[T](len(futs)) + completedFutures = 0 - if completedFutures == len(retValues): - retFuture.complete(retValues) + for i, fut in futs: + proc setCallback(i: int) = + fut.callback = proc(f: Future[T]) = + retValues[i] = f.read() + inc(completedFutures) - setCallback(i) + if completedFutures == len(retValues): + retFuture.complete(retValues) - return retFuture + setCallback(i) + + return retFuture type PDispatcherBase = ref object of RootRef From 81c7be1b35da6a4f7a06b3f081a92b516ee34ee6 Mon Sep 17 00:00:00 2001 From: Konstantin Molchanov Date: Tue, 31 May 2016 23:49:59 +0400 Subject: [PATCH 07/10] Tests: async: Tests for `all` proc added. --- tests/async/tasyncall.nim | 50 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 tests/async/tasyncall.nim diff --git a/tests/async/tasyncall.nim b/tests/async/tasyncall.nim new file mode 100644 index 0000000000..971122ad90 --- /dev/null +++ b/tests/async/tasyncall.nim @@ -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.. Date: Wed, 1 Jun 2016 00:54:49 +0400 Subject: [PATCH 08/10] stdlib: asyncdispatch: `all`: Tests now pass; import sequtils removed; Future[void] case optimized. --- lib/pure/asyncdispatch.nim | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/lib/pure/asyncdispatch.nim b/lib/pure/asyncdispatch.nim index 50349b1046..624836358c 100644 --- a/lib/pure/asyncdispatch.nim +++ b/lib/pure/asyncdispatch.nim @@ -9,7 +9,7 @@ include "system/inclrtl" -import os, oids, tables, strutils, macros, times, heapqueue, sequtils +import os, oids, tables, strutils, macros, times, heapqueue import nativesockets, net, queues @@ -363,7 +363,23 @@ proc all*[T](futs: varargs[Future[T]]): auto = ## in the order they are passed. when T is void: - return foldl(futs, a and b) + var + retFuture = newFuture[void]("asyncdispatch.all") + completedFutures = 0 + + let totalFutures = len(futs) + + for i, fut in futs: + proc setCallback(i: int) = + fut.callback = proc(f: Future[T]) = + inc(completedFutures) + + if completedFutures == totalFutures: + retFuture.complete() + + setCallback(i) + + return retFuture else: var From 83af9888f584f354a5318812e9c90f3f3f210f19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9A=D0=BE=D0=BD=D1=81=D1=82=D0=B0=D0=BD=D1=82=D0=B8?= =?UTF-8?q?=D0=BD=20=D0=9C=D0=BE=D0=BB=D1=87=D0=B0=D0=BD=D0=BE=D0=B2?= Date: Thu, 2 Jun 2016 17:20:46 +0300 Subject: [PATCH 09/10] stdlib: asyncdispatch: `all`: Redundant closure removed. --- lib/pure/asyncdispatch.nim | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/lib/pure/asyncdispatch.nim b/lib/pure/asyncdispatch.nim index 624836358c..7cf1a36e3b 100644 --- a/lib/pure/asyncdispatch.nim +++ b/lib/pure/asyncdispatch.nim @@ -369,15 +369,12 @@ proc all*[T](futs: varargs[Future[T]]): auto = let totalFutures = len(futs) - for i, fut in futs: - proc setCallback(i: int) = - fut.callback = proc(f: Future[T]) = - inc(completedFutures) + for fut in futs: + fut.callback = proc(f: Future[T]) = + inc(completedFutures) - if completedFutures == totalFutures: - retFuture.complete() - - setCallback(i) + if completedFutures == totalFutures: + retFuture.complete() return retFuture From 3538e00fc7b317e4b4adb32ad5fdf2c72d35d481 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9A=D0=BE=D0=BD=D1=81=D1=82=D0=B0=D0=BD=D1=82=D0=B8?= =?UTF-8?q?=D0=BD=20=D0=9C=D0=BE=D0=BB=D1=87=D0=B0=D0=BD=D0=BE=D0=B2?= Date: Thu, 2 Jun 2016 22:23:27 +0300 Subject: [PATCH 10/10] stdlib: asyncdispatch: `all`: Docs updated. --- lib/pure/asyncdispatch.nim | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/lib/pure/asyncdispatch.nim b/lib/pure/asyncdispatch.nim index 7cf1a36e3b..7d765ce75a 100644 --- a/lib/pure/asyncdispatch.nim +++ b/lib/pure/asyncdispatch.nim @@ -356,11 +356,14 @@ proc `or`*[T, Y](fut1: Future[T], fut2: Future[Y]): Future[void] = return retFuture proc all*[T](futs: varargs[Future[T]]): auto = - ## Returns a future which will complete once all futures in ``futs`` - ## complete. + ## 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]``. when T is void: var