Documentation (#311)
* Fix & update asyncloop documentation * Add cancellation documentation * Add documentation generation workflow * pin nim version for doc gen * update readme * fix example * Simplify examples
This commit is contained in:
parent
1e743dc415
commit
a50ac4f642
|
@ -0,0 +1,62 @@
|
|||
name: Docgen
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- docs
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
timeout-minutes: 20
|
||||
|
||||
name: 'Generate & upload documentation'
|
||||
runs-on: 'ubuntu-latest'
|
||||
continue-on-error: true
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
- uses: jiro4989/setup-nim-action@v1
|
||||
with:
|
||||
nim-version: '1.6.6'
|
||||
|
||||
- name: Generate doc
|
||||
run: |
|
||||
nim --version
|
||||
nimble --version
|
||||
nimble install -dy
|
||||
# nim doc can "fail", but the doc is still generated
|
||||
nim doc --git.url:https://github.com/status-im/nim-chronos --git.commit:master --outdir:docs --project chronos || true
|
||||
|
||||
# check that the folder exists
|
||||
ls docs
|
||||
|
||||
- name: Clone the gh-pages branch
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
repository: status-im/nim-chronos
|
||||
ref: gh-pages
|
||||
path: subdoc
|
||||
submodules: true
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Commit & push
|
||||
run: |
|
||||
cd subdoc
|
||||
|
||||
# Update / create this branch doc
|
||||
rm -rf docs
|
||||
mv ../docs .
|
||||
|
||||
# Remove .idx files
|
||||
# NOTE: git also uses idx files in his
|
||||
# internal folder, hence the `*` instead of `.`
|
||||
find * -name "*.idx" -delete
|
||||
git add .
|
||||
git config --global user.email "${{ github.actor }}@users.noreply.github.com"
|
||||
git config --global user.name = "${{ github.actor }}"
|
||||
git commit -a -m "update docs"
|
||||
git push origin gh-pages
|
65
README.md
65
README.md
|
@ -1,7 +1,6 @@
|
|||
# Chronos - An efficient library for asynchronous programming
|
||||
|
||||
[![Github action](https://github.com/status-im/nim-chronos/workflows/nim-chronos%20CI/badge.svg)](https://github.com/status-im/nim-chronos/actions/workflows/ci.yml)
|
||||
[![Windows build status (AppVeyor)](https://img.shields.io/appveyor/ci/nimbus/nim-asyncdispatch2/master.svg?label=Windows "Windows build status (Appveyor)")](https://ci.appveyor.com/project/nimbus/nim-asyncdispatch2)
|
||||
[![License: Apache](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
|
||||
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
|
||||
![Stability: experimental](https://img.shields.io/badge/stability-experimental-orange.svg)
|
||||
|
@ -22,7 +21,7 @@ Chronos is an efficient [async/await](https://en.wikipedia.org/wiki/Async/await)
|
|||
You can use Nim's official package manager Nimble to install Chronos:
|
||||
|
||||
```text
|
||||
nimble install https://github.com/status-im/nim-chronos.git
|
||||
nimble install chronos
|
||||
```
|
||||
|
||||
or add a dependency to your `.nimble` file:
|
||||
|
@ -245,6 +244,68 @@ In the strict mode, `async` functions are checked such that they only raise
|
|||
effects on forward declarations, callbacks and methods using
|
||||
`{.raises: [CatchableError].}` (or more strict) annotations.
|
||||
|
||||
### Cancellation support
|
||||
|
||||
Any running `Future` can be cancelled. This can be used to launch multiple
|
||||
futures, and wait for one of them to finish, and cancel the rest of them,
|
||||
to add timeout, or to let the user cancel a running task.
|
||||
|
||||
```nim
|
||||
# Simple cancellation
|
||||
let future = sleepAsync(10.minutes)
|
||||
future.cancel()
|
||||
|
||||
# Wait for cancellation
|
||||
let future2 = sleepAsync(10.minutes)
|
||||
await future2.cancelAndWait()
|
||||
|
||||
# Race between futures
|
||||
proc retrievePage(uri: string): Future[string] {.async.} =
|
||||
# requires to import uri, chronos/apps/http/httpclient, stew/byteutils
|
||||
let httpSession = HttpSessionRef.new()
|
||||
try:
|
||||
resp = await httpSession.fetch(parseUri(uri))
|
||||
result = string.fromBytes(resp.data)
|
||||
finally:
|
||||
# be sure to always close the session
|
||||
await httpSession.closeWait()
|
||||
|
||||
let
|
||||
futs =
|
||||
@[
|
||||
retrievePage("https://duckduckgo.com/?q=chronos"),
|
||||
retrievePage("https://www.google.fr/search?q=chronos")
|
||||
]
|
||||
|
||||
let finishedFut = await one(futs)
|
||||
for fut in futs:
|
||||
if not fut.finished:
|
||||
fut.cancel()
|
||||
echo "Result: ", await finishedFut
|
||||
```
|
||||
|
||||
When an `await` is cancelled, it will raise a `CancelledError`:
|
||||
```nim
|
||||
proc c1 {.async.} =
|
||||
echo "Before sleep"
|
||||
try:
|
||||
await sleepAsync(10.minutes)
|
||||
echo "After sleep" # not reach due to cancellation
|
||||
except CancelledError as exc:
|
||||
echo "We got cancelled!"
|
||||
raise exc
|
||||
|
||||
proc c2 {.async.} =
|
||||
await c1()
|
||||
echo "Never reached, since the CancelledError got re-raised"
|
||||
|
||||
let work = c2()
|
||||
waitFor(work.cancelAndWait())
|
||||
```
|
||||
|
||||
The `CancelledError` will now travel up the stack like any other exception.
|
||||
It can be caught and handled (for instance, freeing some resources)
|
||||
|
||||
### Multiple async backend support
|
||||
|
||||
Thanks to its powerful macro support, Nim allows `async`/`await` to be
|
||||
|
|
|
@ -22,7 +22,7 @@ export timer
|
|||
|
||||
#{.injectStmt: newGcInvariant().}
|
||||
|
||||
## AsyncDispatch
|
||||
## Chronos
|
||||
## *************
|
||||
##
|
||||
## This module implements asynchronous IO. This includes a dispatcher,
|
||||
|
@ -112,57 +112,33 @@ export timer
|
|||
## ``await socket.send("foobar")``.
|
||||
##
|
||||
## If an awaited future completes with an error, then ``await`` will re-raise
|
||||
## this error. To avoid this, you can use the ``yield`` keyword instead of
|
||||
## ``await``. The following section shows different ways that you can handle
|
||||
## exceptions in async procs.
|
||||
## this error.
|
||||
##
|
||||
## Handling Exceptions
|
||||
## ~~~~~~~~~~~~~~~~~~~
|
||||
## -------------------
|
||||
##
|
||||
## The most reliable way to handle exceptions is to use ``yield`` on a future
|
||||
## then check the future's ``failed`` property. For example:
|
||||
##
|
||||
## .. code-block:: Nim
|
||||
## var future = sock.recv(100)
|
||||
## yield future
|
||||
## if future.failed:
|
||||
## # Handle exception
|
||||
##
|
||||
## The ``async`` procedures also offer limited support for the try statement.
|
||||
## The ``async`` procedures also offer support for the try statement.
|
||||
##
|
||||
## .. code-block:: Nim
|
||||
## try:
|
||||
## let data = await sock.recv(100)
|
||||
## echo("Received ", data)
|
||||
## except:
|
||||
## # Handle exception
|
||||
##
|
||||
## Unfortunately the semantics of the try statement may not always be correct,
|
||||
## and occasionally the compilation may fail altogether.
|
||||
## As such it is better to use the former style when possible.
|
||||
##
|
||||
## except CancelledError as exc:
|
||||
## # Handle exc
|
||||
##
|
||||
## Discarding futures
|
||||
## ------------------
|
||||
##
|
||||
## Futures should **never** be discarded. This is because they may contain
|
||||
## errors. If you do not care for the result of a Future then you should
|
||||
## use the ``asyncCheck`` procedure instead of the ``discard`` keyword.
|
||||
##
|
||||
## Examples
|
||||
## --------
|
||||
##
|
||||
## For examples take a look at the documentation for the modules implementing
|
||||
## asynchronous IO. A good place to start is the
|
||||
## `asyncnet module <asyncnet.html>`_.
|
||||
## use the ``asyncSpawn`` procedure instead of the ``discard`` keyword.
|
||||
## ``asyncSpawn`` will transform any exception thrown by the called procedure
|
||||
## to a Defect
|
||||
##
|
||||
## Limitations/Bugs
|
||||
## ----------------
|
||||
##
|
||||
## * The effect system (``raises: []``) does not work with async procedures.
|
||||
## * Can't await in a ``except`` body
|
||||
## * Forward declarations for async procs are broken,
|
||||
## link includes workaround: https://github.com/nim-lang/Nim/issues/3182.
|
||||
|
||||
# TODO: Check if yielded future is nil and throw a more meaningful exception
|
||||
|
||||
|
|
Loading…
Reference in New Issue