diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 0000000..e26fefc --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,32 @@ +name: CI +on: + push: + branches: [master] + pull_request: + branches: [master] +jobs: + build: + name: Run + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest] + dc: [dmd-latest, ldc-latest] + runs-on: ${{ matrix.os }} + timeout-minutes: 30 + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + # Requiried for codecov action + fetch-depth: 2 + - uses: dlang-community/setup-dlang@0a7469b93f791d83f30932c6fd105796c6966e20 # v2.0.0 + with: + compiler: ${{ matrix.dc }} + - name: "Build & Test" + shell: bash + run: | + dub test --compiler=$DC -b unittest-cov + - name: Upload coverage to Codecov + uses: codecov/codecov-action@1af58845a975a7985b0beb0cbe6fbbb71a41dbad # v5.5.3 + with: + flags: unittests diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml new file mode 100644 index 0000000..2b66aec --- /dev/null +++ b/.github/workflows/pre-commit.yml @@ -0,0 +1,13 @@ +name: Pre-commit +on: + push: + branches: [master] + pull_request: + branches: [master] +jobs: + pre-commit: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 + - uses: pre-commit/action@2c7b3805fd2a0fd8c1884dcaebf91fc102a13ecd # v3.0.1 diff --git a/.gitignore b/.gitignore index 44631cb..75608d8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ -dub.selections.json bin/ build/ .dub diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..8d7126e --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,40 @@ +# See CONTRIBUTING.md for instructions. +# See https://pre-commit.com for more information +# See https://pre-commit.com/hooks.html for more hooks +# Commitizen runs in commit-msg stage +# but we don't want to run the other hooks on commit messages +default_stages: [pre-commit] +repos: + - repo: meta + hooks: + - id: check-hooks-apply + - id: check-useless-excludes + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v6.0.0 + hooks: + - id: check-json + - id: check-shebang-scripts-are-executable + - id: check-yaml + - id: destroyed-symlinks + - id: detect-private-key + - id: end-of-file-fixer + - id: trailing-whitespace + # Enforce that commit messages allow for later changelog generation + - repo: https://github.com/commitizen-tools/commitizen + rev: v4.13.9 + hooks: + # Requires that commitizen is already installed + - id: commitizen + stages: [commit-msg] + - repo: https://github.com/pre-commit/mirrors-prettier + rev: v3.1.0 + hooks: + - id: prettier + - repo: https://github.com/google/yamlfmt + rev: v0.21.0 + hooks: + - id: yamlfmt + - repo: https://github.com/crate-ci/typos + rev: v1.44.0 + hooks: + - id: typos diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index cf18889..0000000 --- a/.travis.yml +++ /dev/null @@ -1,2 +0,0 @@ -language: d -sudo: false diff --git a/README.md b/README.md index a098ff5..d10e72f 100644 --- a/README.md +++ b/README.md @@ -1,30 +1,33 @@ -[![Build Status](https://travis-ci.org/dcarp/asynchronous.png?branch=master)](https://travis-ci.org/dcarp/asynchronous) - # `asynchronous` + This library provides infrastructure for writing concurrent code using coroutines, multiplexing I/O access over sockets and other resources, running network clients and servers, and other related primitives. -*It implements most of the python 3 [asyncio API](https://docs.python.org/3/library/asyncio.html).* +_It implements most of the python 3 [asyncio API](https://docs.python.org/3/library/asyncio.html)._ #### API Reference + Can be found at: http://dcarp.github.io/asynchronous/index.html #### Implementation status -* Timers (done) -* Futures, Tasks (done) -* Sockets (done) -* Streams (done) -* Subprocesses (not implemented) -* Locks and semaphores (done) -* Queues (done) + +- Timers (done) +- Futures, Tasks (done) +- Sockets (done) +- Streams (done) +- Subprocesses (not implemented) +- Locks and semaphores (done) +- Queues (done) #### Why yet another async library? What is wrong with vibe.d? -* `asynchronous` is a library and not a framework -* it is not web-oriented, compatible with `std.socket` -* arguably nicer API -* event loop start/stop control -* uses `@Coroutine` UDA to mark functions that could trigger a task (fiber) switch, although this is not enforced yet by the compiler. + +- `asynchronous` is a library and not a framework +- it is not web-oriented, compatible with `std.socket` +- arguably nicer API +- event loop start/stop control +- uses `@Coroutine` UDA to mark functions that could trigger a task (fiber) switch, although this is not enforced yet by the compiler. #### Examples and tutorials + Some small examples can be found in the test directory or as unittests. For larger examples please use the Python/asyncio resources. Please keep in mind that, in contrast with Python/asyncio, in D a coroutine MUST be called from within a Task, otherwise it causes a run-time error on the fiber switch. Basic rule: if not called from another coroutine, any coroutine call need to be wrapped by `ensureFuture` or `EventLoop.createTask`. diff --git a/dub.json b/dub.json index eef3ed2..2e2e63f 100644 --- a/dub.json +++ b/dub.json @@ -1,26 +1,24 @@ { - "name": "asynchronous", - "description": "Asynchronous library for D", - "license": "Boost 1.0", - "copyright": "Copyright © 2015-2016 Dragoş Carp", - "authors": [ - "Dragoş Carp" - ], - "targetType": "library", - "targetPath": "build", - "workingDirectory": "build", - "dependencies": { - "libasync": "~>0.8.3" + "name": "asynchronous", + "description": "Asynchronous library for D", + "license": "Boost 1.0", + "copyright": "Copyright © 2015-2016 Dragoş Carp", + "authors": ["Dragoş Carp"], + "targetType": "library", + "targetPath": "build", + "workingDirectory": "build", + "dependencies": { + "libasync": "~>0.9.0" + }, + "configurations": [ + { + "name": "library" }, - "configurations": [ - { - "name": "library" - }, - { - "name": "unittest", - "targetType": "executable", - "sourcePaths": ["test"], - "mainSourceFile": "test/main.d" - } - ] + { + "name": "unittest", + "targetType": "executable", + "sourcePaths": ["test"], + "mainSourceFile": "test/main.d" + } + ] } diff --git a/dub.selections.json b/dub.selections.json new file mode 100644 index 0000000..b84ab1b --- /dev/null +++ b/dub.selections.json @@ -0,0 +1,7 @@ +{ + "fileVersion": 1, + "versions": { + "libasync": "0.9.7", + "memutils": "1.0.11" + } +} diff --git a/renovate.json b/renovate.json index 5db72dd..e816b20 100644 --- a/renovate.json +++ b/renovate.json @@ -1,6 +1,4 @@ { "$schema": "https://docs.renovatebot.com/renovate-schema.json", - "extends": [ - "config:recommended" - ] + "extends": [":enablePreCommit", "config:best-practices"] } diff --git a/src/asynchronous/events.d b/src/asynchronous/events.d index debaae9..1bc0cfe 100644 --- a/src/asynchronous/events.d +++ b/src/asynchronous/events.d @@ -128,7 +128,7 @@ auto callback(Dg, Args...)(EventLoop eventLoop, Dg dg, Args args) alias ExceptionHandler = void delegate(EventLoop, ExceptionContext); /** - * Exception conxtext for event exceptions + * Exception context for event exceptions */ struct ExceptionContext { @@ -542,7 +542,7 @@ abstract class EventLoop * empty, hostname matching is disabled (which is a serious security * risk, allowing for man-in-the-middle-attacks). * - * addressFamily = optional adress family. + * addressFamily = optional address family. * * protocolType = optional protocol. * diff --git a/src/asynchronous/libasync/events.d b/src/asynchronous/libasync/events.d index 078a77f..8d86352 100644 --- a/src/asynchronous/libasync/events.d +++ b/src/asynchronous/libasync/events.d @@ -215,7 +215,7 @@ package class LibasyncEventLoop : EventLoop AddressInfoFlags addressInfoFlags = UNSPECIFIED!AddressInfoFlags) { // no async implementation in libasync yet, use the - // std.socket.getAddresInfo implementation; + // std.socket.getAddressInfo implementation; return std.socket.getAddressInfo(host, service, addressFamily, socketType, protocolType, addressInfoFlags); } @@ -562,17 +562,17 @@ private final class LibasyncTransport : AbstractBaseTransport, Transport if (low.isNull) high = 64 * 1024; else - high = 4 * low; + high = 4 * low.get; } if (low.isNull) - low = high / 4; + low = high.get / 4; - if (high < low) - low = high; + if (high.get < low.get) + low = high.get; - this.writeBufferLimits.high = high; - this.writeBufferLimits.low = low; + this.writeBufferLimits.high = high.get; + this.writeBufferLimits.low = low.get; } void write(const(void)[] data)