mirror of
https://github.com/status-im/nim-chronos.git
synced 2025-02-03 15:04:38 +00:00
Undeprecate or
operation. (#93)
* Undeprecate `or` operation. Fix `or` for already finished futures. Add tests. * Bump version to 2.3.9.
This commit is contained in:
parent
9ea1017a06
commit
2ecc5500c2
@ -1,5 +1,5 @@
|
|||||||
packageName = "chronos"
|
packageName = "chronos"
|
||||||
version = "2.3.8"
|
version = "2.3.9"
|
||||||
author = "Status Research & Development GmbH"
|
author = "Status Research & Development GmbH"
|
||||||
description = "Chronos"
|
description = "Chronos"
|
||||||
license = "Apache License 2.0 or MIT"
|
license = "Apache License 2.0 or MIT"
|
||||||
|
@ -490,13 +490,15 @@ proc `and`*[T, Y](fut1: Future[T], fut2: Future[Y]): Future[void] {.
|
|||||||
retFuture.cancelCallback = cancellation
|
retFuture.cancelCallback = cancellation
|
||||||
return retFuture
|
return retFuture
|
||||||
|
|
||||||
proc `or`*[T, Y](fut1: Future[T], fut2: Future[Y]): Future[void] {.
|
proc `or`*[T, Y](fut1: Future[T], fut2: Future[Y]): Future[void] =
|
||||||
deprecated: "Use one[T](varargs[Future[T]])".} =
|
|
||||||
## Returns a future which will complete once either ``fut1`` or ``fut2``
|
## Returns a future which will complete once either ``fut1`` or ``fut2``
|
||||||
## complete.
|
## complete.
|
||||||
##
|
##
|
||||||
|
## If ``fut1`` or ``fut2`` will fail, result future will also fail with an
|
||||||
|
## error stored in ``fut1`` or ``fut2`` respectively.
|
||||||
|
##
|
||||||
## If cancelled, ``fut1`` and ``fut2`` futures WILL NOT BE cancelled.
|
## If cancelled, ``fut1`` and ``fut2`` futures WILL NOT BE cancelled.
|
||||||
var retFuture = newFuture[void]("chronos.`or`")
|
var retFuture = newFuture[void]("chronos.or")
|
||||||
proc cb(udata: pointer) {.gcsafe.} =
|
proc cb(udata: pointer) {.gcsafe.} =
|
||||||
if not(retFuture.finished()):
|
if not(retFuture.finished()):
|
||||||
var fut = cast[FutureBase](udata)
|
var fut = cast[FutureBase](udata)
|
||||||
@ -504,16 +506,33 @@ proc `or`*[T, Y](fut1: Future[T], fut2: Future[Y]): Future[void] {.
|
|||||||
fut2.removeCallback(cb)
|
fut2.removeCallback(cb)
|
||||||
else:
|
else:
|
||||||
fut1.removeCallback(cb)
|
fut1.removeCallback(cb)
|
||||||
if fut.failed(): retFuture.fail(fut.error)
|
if fut.failed():
|
||||||
else: retFuture.complete()
|
retFuture.fail(fut.error)
|
||||||
fut1.callback = cb
|
else:
|
||||||
fut2.callback = cb
|
retFuture.complete()
|
||||||
|
|
||||||
proc cancellation(udata: pointer) {.gcsafe.} =
|
proc cancellation(udata: pointer) {.gcsafe.} =
|
||||||
# On cancel we remove all our callbacks only.
|
# On cancel we remove all our callbacks only.
|
||||||
fut1.removeCallback(cb)
|
fut1.removeCallback(cb)
|
||||||
fut2.removeCallback(cb)
|
fut2.removeCallback(cb)
|
||||||
|
|
||||||
|
if fut1.finished():
|
||||||
|
if fut1.failed():
|
||||||
|
retFuture.fail(fut1.error)
|
||||||
|
else:
|
||||||
|
retFuture.complete()
|
||||||
|
return retFuture
|
||||||
|
|
||||||
|
if fut2.finished():
|
||||||
|
if fut2.failed():
|
||||||
|
retFuture.fail(fut2.error)
|
||||||
|
else:
|
||||||
|
retFuture.complete()
|
||||||
|
return retFuture
|
||||||
|
|
||||||
|
fut1.addCallback(cb)
|
||||||
|
fut2.addCallback(cb)
|
||||||
|
|
||||||
retFuture.cancelCallback = cancellation
|
retFuture.cancelCallback = cancellation
|
||||||
return retFuture
|
return retFuture
|
||||||
|
|
||||||
|
@ -684,6 +684,76 @@ suite "Future[T] behavior test suite":
|
|||||||
result = fut1.finished() and not(fut1.failed()) and fut1.read() == f10 and
|
result = fut1.finished() and not(fut1.failed()) and fut1.read() == f10 and
|
||||||
fut2.finished() and not(fut2.failed()) and fut2.read() == f21
|
fut2.finished() and not(fut2.failed()) and fut2.read() == f21
|
||||||
|
|
||||||
|
proc waitForNeLocal[T](fut: Future[T]): Future[T] =
|
||||||
|
## **Blocks** the current thread until the specified future completes.
|
||||||
|
while not(fut.finished()):
|
||||||
|
poll()
|
||||||
|
result = fut
|
||||||
|
|
||||||
|
proc testOr(): bool =
|
||||||
|
|
||||||
|
proc client1() {.async.} =
|
||||||
|
await sleepAsync(200.milliseconds)
|
||||||
|
|
||||||
|
proc client2() {.async.} =
|
||||||
|
await sleepAsync(300.milliseconds)
|
||||||
|
|
||||||
|
proc client3() {.async.} =
|
||||||
|
await sleepAsync(100.milliseconds)
|
||||||
|
if true:
|
||||||
|
raise newException(ValueError, "")
|
||||||
|
|
||||||
|
proc client4() {.async.} =
|
||||||
|
await sleepAsync(400.milliseconds)
|
||||||
|
if true:
|
||||||
|
raise newException(KeyError, "")
|
||||||
|
|
||||||
|
var f1 = waitForNeLocal(client1() or client2())
|
||||||
|
var f2 = waitForNeLocal(client2() or client1())
|
||||||
|
var f3 = waitForNeLocal(client1() or client4())
|
||||||
|
var f4 = waitForNeLocal(client2() or client4())
|
||||||
|
var f5 = waitForNeLocal(client1() or client3())
|
||||||
|
var f6 = waitForNeLocal(client3() or client1())
|
||||||
|
var f7 = waitForNeLocal(client2() or client4())
|
||||||
|
var f8 = waitForNeLocal(client4() or client2())
|
||||||
|
var f9 = waitForNeLocal(client3() or client4())
|
||||||
|
var f10 = waitForNeLocal(client4() or client3())
|
||||||
|
|
||||||
|
result = (f1.finished() and not(f1.failed())) and
|
||||||
|
(f2.finished() and not(f2.failed())) and
|
||||||
|
(f3.finished() and not(f3.failed())) and
|
||||||
|
(f4.finished() and not(f4.failed())) and
|
||||||
|
(f5.finished() and f5.failed()) and
|
||||||
|
(f6.finished() and f6.failed()) and
|
||||||
|
(f7.finished() and not(f7.failed())) and
|
||||||
|
(f8.finished() and not(f8.failed())) and
|
||||||
|
(f9.finished() and f9.failed()) and
|
||||||
|
(f10.finished() and f10.failed())
|
||||||
|
|
||||||
|
proc testOrCompleted(): 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 f1 = client1() or client2()
|
||||||
|
var f2 = client1() or client3()
|
||||||
|
var f3 = client2() or client3()
|
||||||
|
var f4 = client2() or client1()
|
||||||
|
var f5 = client3() or client1()
|
||||||
|
var f6 = client3() or client2()
|
||||||
|
|
||||||
|
result = (f1.finished() and not(f1.failed())) and
|
||||||
|
(f2.finished() and not(f2.failed())) and
|
||||||
|
(f3.finished() and f3.failed()) and
|
||||||
|
(f4.finished() and f4.failed()) and
|
||||||
|
(f5.finished() and not(f5.failed())) and
|
||||||
|
(f6.finished() and f6.failed())
|
||||||
|
|
||||||
proc testCancelIter(): bool =
|
proc testCancelIter(): bool =
|
||||||
var completed = 0
|
var completed = 0
|
||||||
|
|
||||||
@ -907,6 +977,11 @@ suite "Future[T] behavior test suite":
|
|||||||
test "one() already completed test":
|
test "one() already completed test":
|
||||||
check testOneCompleted() == true
|
check testOneCompleted() == true
|
||||||
|
|
||||||
|
test "or() test":
|
||||||
|
check testOr() == true
|
||||||
|
test "or() already completed test":
|
||||||
|
check testOrCompleted() == true
|
||||||
|
|
||||||
test "cancel() async procedure test":
|
test "cancel() async procedure test":
|
||||||
check testCancelIter() == true
|
check testCancelIter() == true
|
||||||
test "cancelAndWait() test":
|
test "cancelAndWait() test":
|
||||||
|
Loading…
x
Reference in New Issue
Block a user