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
|
# 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)
|
[![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: 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)
|
[![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)
|
![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:
|
You can use Nim's official package manager Nimble to install Chronos:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
nimble install https://github.com/status-im/nim-chronos.git
|
nimble install chronos
|
||||||
```
|
```
|
||||||
|
|
||||||
or add a dependency to your `.nimble` file:
|
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
|
effects on forward declarations, callbacks and methods using
|
||||||
`{.raises: [CatchableError].}` (or more strict) annotations.
|
`{.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
|
### Multiple async backend support
|
||||||
|
|
||||||
Thanks to its powerful macro support, Nim allows `async`/`await` to be
|
Thanks to its powerful macro support, Nim allows `async`/`await` to be
|
||||||
|
|
|
@ -22,7 +22,7 @@ export timer
|
||||||
|
|
||||||
#{.injectStmt: newGcInvariant().}
|
#{.injectStmt: newGcInvariant().}
|
||||||
|
|
||||||
## AsyncDispatch
|
## Chronos
|
||||||
## *************
|
## *************
|
||||||
##
|
##
|
||||||
## This module implements asynchronous IO. This includes a dispatcher,
|
## This module implements asynchronous IO. This includes a dispatcher,
|
||||||
|
@ -112,57 +112,33 @@ export timer
|
||||||
## ``await socket.send("foobar")``.
|
## ``await socket.send("foobar")``.
|
||||||
##
|
##
|
||||||
## If an awaited future completes with an error, then ``await`` will re-raise
|
## 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
|
## this error.
|
||||||
## ``await``. The following section shows different ways that you can handle
|
|
||||||
## exceptions in async procs.
|
|
||||||
##
|
##
|
||||||
## Handling Exceptions
|
## Handling Exceptions
|
||||||
## ~~~~~~~~~~~~~~~~~~~
|
## -------------------
|
||||||
##
|
##
|
||||||
## The most reliable way to handle exceptions is to use ``yield`` on a future
|
## The ``async`` procedures also offer support for the try statement.
|
||||||
## 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.
|
|
||||||
##
|
##
|
||||||
## .. code-block:: Nim
|
## .. code-block:: Nim
|
||||||
## try:
|
## try:
|
||||||
## let data = await sock.recv(100)
|
## let data = await sock.recv(100)
|
||||||
## echo("Received ", data)
|
## echo("Received ", data)
|
||||||
## except:
|
## except CancelledError as exc:
|
||||||
## # Handle exception
|
## # Handle exc
|
||||||
##
|
|
||||||
## 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.
|
|
||||||
##
|
|
||||||
##
|
##
|
||||||
## Discarding futures
|
## Discarding futures
|
||||||
## ------------------
|
## ------------------
|
||||||
##
|
##
|
||||||
## Futures should **never** be discarded. This is because they may contain
|
## 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
|
## errors. If you do not care for the result of a Future then you should
|
||||||
## use the ``asyncCheck`` procedure instead of the ``discard`` keyword.
|
## use the ``asyncSpawn`` procedure instead of the ``discard`` keyword.
|
||||||
##
|
## ``asyncSpawn`` will transform any exception thrown by the called procedure
|
||||||
## Examples
|
## to a Defect
|
||||||
## --------
|
|
||||||
##
|
|
||||||
## 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>`_.
|
|
||||||
##
|
##
|
||||||
## Limitations/Bugs
|
## Limitations/Bugs
|
||||||
## ----------------
|
## ----------------
|
||||||
##
|
##
|
||||||
## * The effect system (``raises: []``) does not work with async procedures.
|
## * 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
|
# TODO: Check if yielded future is nil and throw a more meaningful exception
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue