mirror of
https://github.com/logos-storage/nim-chronos.git
synced 2026-01-07 16:03:09 +00:00
Update README regarding cancellation (#450)
* Update README regarding cancellation * Apply suggestions from code review Co-authored-by: Eugene Kabanov <eugene.kabanov@status.im> --------- Co-authored-by: Jacek Sieka <jacek@status.im> Co-authored-by: Eugene Kabanov <eugene.kabanov@status.im>
This commit is contained in:
parent
f56d286687
commit
12dc36cfee
81
README.md
81
README.md
@ -301,45 +301,64 @@ effects on forward declarations, callbacks and methods using
|
|||||||
|
|
||||||
### Cancellation support
|
### Cancellation support
|
||||||
|
|
||||||
Any running `Future` can be cancelled. This can be used to launch multiple
|
Any running `Future` can be cancelled. This can be used for timeouts,
|
||||||
futures, and wait for one of them to finish, and cancel the rest of them,
|
to let a user cancel a running task, to start multiple futures in parallel
|
||||||
to add timeout, or to let the user cancel a running task.
|
and cancel them as soon as one finishes, etc.
|
||||||
|
|
||||||
```nim
|
```nim
|
||||||
# Simple cancellation
|
import chronos/apps/http/httpclient
|
||||||
let future = sleepAsync(10.minutes)
|
|
||||||
future.cancel()
|
|
||||||
|
|
||||||
# Wait for cancellation
|
proc cancellationExample() {.async.} =
|
||||||
let future2 = sleepAsync(10.minutes)
|
# Simple cancellation
|
||||||
await future2.cancelAndWait()
|
let future = sleepAsync(10.minutes)
|
||||||
|
future.cancelSoon()
|
||||||
|
# `cancelSoon` will not wait for the cancellation
|
||||||
|
# to be finished, so the Future could still be
|
||||||
|
# pending at this point.
|
||||||
|
|
||||||
# Race between futures
|
# Wait for cancellation
|
||||||
proc retrievePage(uri: string): Future[string] {.async.} =
|
let future2 = sleepAsync(10.minutes)
|
||||||
# requires to import uri, chronos/apps/http/httpclient, stew/byteutils
|
await future2.cancelAndWait()
|
||||||
let httpSession = HttpSessionRef.new()
|
# Using `cancelAndWait`, we know that future2 isn't
|
||||||
try:
|
# pending anymore. However, it could have completed
|
||||||
resp = await httpSession.fetch(parseUri(uri))
|
# before cancellation happened (in which case, it
|
||||||
result = string.fromBytes(resp.data)
|
# will hold a value)
|
||||||
finally:
|
|
||||||
# be sure to always close the session
|
|
||||||
await httpSession.closeWait()
|
|
||||||
|
|
||||||
let
|
# Race between futures
|
||||||
futs =
|
proc retrievePage(uri: string): Future[string] {.async.} =
|
||||||
@[
|
let httpSession = HttpSessionRef.new()
|
||||||
retrievePage("https://duckduckgo.com/?q=chronos"),
|
try:
|
||||||
retrievePage("https://www.google.fr/search?q=chronos")
|
let resp = await httpSession.fetch(parseUri(uri))
|
||||||
]
|
return bytesToString(resp.data)
|
||||||
|
finally:
|
||||||
|
# be sure to always close the session
|
||||||
|
# `finally` will run also during cancellation -
|
||||||
|
# `noCancel` ensures that `closeWait` doesn't get cancelled
|
||||||
|
await noCancel(httpSession.closeWait())
|
||||||
|
|
||||||
let finishedFut = await one(futs)
|
let
|
||||||
for fut in futs:
|
futs =
|
||||||
if not fut.finished:
|
@[
|
||||||
fut.cancel()
|
retrievePage("https://duckduckgo.com/?q=chronos"),
|
||||||
echo "Result: ", await finishedFut
|
retrievePage("https://www.google.fr/search?q=chronos")
|
||||||
|
]
|
||||||
|
|
||||||
|
let finishedFut = await one(futs)
|
||||||
|
for fut in futs:
|
||||||
|
if not fut.finished:
|
||||||
|
fut.cancelSoon()
|
||||||
|
echo "Result: ", await finishedFut
|
||||||
|
|
||||||
|
waitFor(cancellationExample())
|
||||||
```
|
```
|
||||||
|
|
||||||
When an `await` is cancelled, it will raise a `CancelledError`:
|
Even if cancellation is initiated, it is not guaranteed that
|
||||||
|
the operation gets cancelled - the future might still be completed
|
||||||
|
or fail depending on the ordering of events and the specifics of
|
||||||
|
the operation.
|
||||||
|
|
||||||
|
If the future indeed gets cancelled, `await` will raise a
|
||||||
|
`CancelledError` as is likely to happen in the following example:
|
||||||
```nim
|
```nim
|
||||||
proc c1 {.async.} =
|
proc c1 {.async.} =
|
||||||
echo "Before sleep"
|
echo "Before sleep"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user