Skip to content

Commit

Permalink
Merge pull request #21 from lambdalisue/ref
Browse files Browse the repository at this point in the history
Refactor
  • Loading branch information
lambdalisue authored Jan 6, 2024
2 parents 7e68d46 + 1b3a897 commit f61dbcb
Show file tree
Hide file tree
Showing 27 changed files with 211 additions and 158 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- uses: denoland/setup-deno@v1
with:
deno-version: ${{ env.DENO_VERSION }}
Expand All @@ -30,7 +30,7 @@ jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- uses: denoland/setup-deno@v1
with:
deno-version: ${{ env.DENO_VERSION }}
Expand Down
50 changes: 0 additions & 50 deletions .github/workflows/udd.yml

This file was deleted.

62 changes: 44 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Asynchronous primitive modules for [Deno][deno].
until all of them have reached a certain point of execution before continuing.

```ts
import { Barrier } from "./barrier.ts";
import { Barrier } from "https://deno.land/x/async@$MODULE_VERSION/barrier.ts";

const barrier = new Barrier(3);

Expand All @@ -32,14 +32,40 @@ worker(2);
worker(3);
```

### WaitGroup

`WaitGroup` is a synchronization primitive that enables promises to coordinate
and synchronize their execution. It is particularly useful in scenarios where a
specific number of tasks must complete before the program can proceed.

```ts
import { delay } from "https://deno.land/std@0.211.0/async/delay.ts";
import { WaitGroup } from "https://deno.land/x/async@$MODULE_VERSION/wait_group.ts";

const wg = new WaitGroup();

async function worker(id: number) {
wg.add(1);
console.log(`worker ${id} is waiting`);
await delay(100);
console.log(`worker ${id} is done`);
wg.done();
}

worker(1);
worker(2);
worker(3);
await wg.wait();
```

### Lock/RwLock

`Lock` is a mutual exclusion lock that provides safe concurrent access to a
shared value.

```ts
import { AsyncValue } from "./testutil.ts";
import { Lock } from "./lock.ts";
import { AsyncValue } from "https://deno.land/x/async@$MODULE_VERSION/testutil.ts";
import { Lock } from "https://deno.land/x/async@$MODULE_VERSION/lock.ts";

// Critical section
const count = new Lock(new AsyncValue(0));
Expand All @@ -55,8 +81,8 @@ as long as there are no writers holding the lock. Writers block all other
readers and writers until the write operation completes.

```ts
import { AsyncValue } from "./testutil.ts";
import { RwLock } from "./rw_lock.ts";
import { AsyncValue } from "https://deno.land/x/async@$MODULE_VERSION/testutil.ts";
import { RwLock } from "https://deno.land/x/async@$MODULE_VERSION/rw_lock.ts";

const count = new RwLock(new AsyncValue(0));

Expand Down Expand Up @@ -86,8 +112,8 @@ This is a low-level primitive. Use `Lock` instead of `Mutex` if you need to
access a shared value concurrently.

```ts
import { AsyncValue } from "./testutil.ts";
import { Mutex } from "./mutex.ts";
import { AsyncValue } from "https://deno.land/x/async@$MODULE_VERSION/testutil.ts";
import { Mutex } from "https://deno.land/x/async@$MODULE_VERSION/mutex.ts";

const count = new AsyncValue(0);

Expand All @@ -112,9 +138,9 @@ try {
notification.

```ts
import { assertEquals } from "https://deno.land/std@0.186.0/testing/asserts.ts";
import { promiseState } from "./state.ts";
import { Notify } from "./notify.ts";
import { assertEquals } from "https://deno.land/std@0.211.0/assert/mod.ts";
import { promiseState } from "https://deno.land/x/async@$MODULE_VERSION/state.ts";
import { Notify } from "https://deno.land/x/async@$MODULE_VERSION/notify.ts";

const notify = new Notify();
const waiter1 = notify.notified();
Expand All @@ -133,8 +159,8 @@ assertEquals(await promiseState(waiter2), "fulfilled");
with optional waiting when popping elements from an empty queue.

```ts
import { assertEquals } from "https://deno.land/std@0.186.0/testing/asserts.ts";
import { Queue } from "./queue.ts";
import { assertEquals } from "https://deno.land/std@0.211.0/assert/mod.ts";
import { Queue } from "https://deno.land/x/async@$MODULE_VERSION/queue.ts";

const queue = new Queue<number>();
queue.push(1);
Expand All @@ -149,8 +175,8 @@ assertEquals(await queue.pop(), 3);
with optional waiting when popping elements from an empty stack.

```ts
import { assertEquals } from "https://deno.land/std@0.186.0/testing/asserts.ts";
import { Stack } from "./stack.ts";
import { assertEquals } from "https://deno.land/std@0.211.0/assert/mod.ts";
import { Stack } from "https://deno.land/x/async@$MODULE_VERSION/stack.ts";

const stack = new Stack<number>();
stack.push(1);
Expand All @@ -167,7 +193,7 @@ A semaphore that allows a limited number of concurrent executions of an
operation.

```ts
import { Semaphore } from "./semaphore.ts";
import { Semaphore } from "https://deno.land/x/async@$MODULE_VERSION/semaphore.ts";

const sem = new Semaphore(5);
const worker = () => {
Expand All @@ -184,7 +210,7 @@ await Promise.all([...Array(10)].map(() => worker()));
purpose.

```typescript
import { promiseState } from "https://deno.land/x/async/mod.ts";
import { promiseState } from "https://deno.land/x/async@$MODULE_VERSION/mod.ts";

const p1 = Promise.resolve("Resolved promise");
console.log(await promiseState(p1)); // fulfilled
Expand All @@ -202,8 +228,8 @@ console.log(await promiseState(p3)); // pending
asynchronously.

```ts
import { assertEquals } from "https://deno.land/std@0.186.0/testing/asserts.ts";
import { AsyncValue } from "./testutil.ts";
import { assertEquals } from "https://deno.land/std@0.211.0/assert/mod.ts";
import { AsyncValue } from "https://deno.land/x/async@$MODULE_VERSION/testutil.ts";

const v = new AsyncValue(0);
assertEquals(await v.get(), 0);
Expand Down
2 changes: 1 addition & 1 deletion barrier.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { Notify } from "./notify.ts";
* unblock and continue executing.
*
* ```ts
* import { Barrier } from "./barrier.ts";
* import { Barrier } from "https://deno.land/x/async@$MODULE_VERSION/barrier.ts";
*
* const barrier = new Barrier(3);
*
Expand Down
2 changes: 1 addition & 1 deletion barrier_test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { assertEquals } from "https://deno.land/std@0.186.0/testing/asserts.ts";
import { assertEquals } from "https://deno.land/std@0.211.0/assert/mod.ts";
import { Barrier } from "./barrier.ts";

Deno.test("Barrier", async (t) => {
Expand Down
13 changes: 10 additions & 3 deletions deno.jsonc
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
{
"lock": false,
"imports": {
"https://deno.land/x/async@$MODULE_VERSION/": "./"
},
"tasks": {
"test": "deno test -A --parallel",
"check": "deno check $(find . -name '*.ts')",
"upgrade": "deno run -A https://deno.land/x/udd/main.ts $(find . -name '*.ts')"
"test": "deno test -A --parallel --shuffle --doc",
"test:coverage": "deno task test --coverage=.coverage",
"check": "deno check ./**/*.ts",
"coverage": "deno coverage .coverage",
"upgrade": "deno run -q -A https://deno.land/x/molt@0.14.2/cli.ts ./**/*.ts",
"upgrade:commit": "deno task -q upgrade --commit --prefix :package: --pre-commit=fmt"
}
}
20 changes: 0 additions & 20 deletions deno.lock

This file was deleted.

4 changes: 2 additions & 2 deletions lock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import { Mutex } from "./mutex.ts";
* A mutual exclusion lock that provides safe concurrent access to a shared value.
*
* ```ts
* import { AsyncValue } from "./testutil.ts";
* import { Lock } from "./lock.ts";
* import { AsyncValue } from "https://deno.land/x/async@$MODULE_VERSION/testutil.ts";
* import { Lock } from "https://deno.land/x/async@$MODULE_VERSION/lock.ts";
*
* // Critical section
* const count = new Lock(new AsyncValue(0));
Expand Down
2 changes: 1 addition & 1 deletion lock_test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { assertEquals } from "https://deno.land/std@0.186.0/testing/asserts.ts";
import { assertEquals } from "https://deno.land/std@0.211.0/assert/mod.ts";
import { AsyncValue } from "./testutil.ts";
import { Lock } from "./lock.ts";

Expand Down
1 change: 1 addition & 0 deletions mod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ export * from "./semaphore.ts";
export * from "./stack.ts";
export * from "./state.ts";
export * from "./testutil.ts";
export * from "./wait_group.ts";
16 changes: 6 additions & 10 deletions mutex.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
import {
Deferred,
deferred,
} from "https://deno.land/std@0.186.0/async/deferred.ts";

/**
* A mutex (mutual exclusion) is a synchronization primitive that grants
* exclusive access to a shared resource.
Expand All @@ -11,8 +6,8 @@ import {
* concurrently.
*
* ```ts
* import { AsyncValue } from "./testutil.ts";
* import { Mutex } from "./mutex.ts";
* import { AsyncValue } from "https://deno.land/x/async@$MODULE_VERSION/testutil.ts";
* import { Mutex } from "https://deno.land/x/async@$MODULE_VERSION/mutex.ts";
*
* const count = new AsyncValue(0);
*
Expand All @@ -32,7 +27,7 @@ import {
* ```
*/
export class Mutex {
#waiters: Deferred<void>[] = [];
#waiters: { promise: Promise<void>; resolve: () => void }[] = [];

/**
* Returns true if the mutex is locked, false otherwise.
Expand All @@ -47,9 +42,10 @@ export class Mutex {
*/
async acquire(): Promise<void> {
const waiters = [...this.#waiters];
this.#waiters.push(deferred());
const { promise, resolve } = Promise.withResolvers<void>();
this.#waiters.push({ promise, resolve });
if (waiters.length) {
await Promise.all(waiters);
await Promise.all(waiters.map(({ promise }) => promise));
}
}

Expand Down
2 changes: 1 addition & 1 deletion mutex_test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { assertEquals } from "https://deno.land/std@0.186.0/testing/asserts.ts";
import { assertEquals } from "https://deno.land/std@0.211.0/assert/mod.ts";
import { AsyncValue } from "./testutil.ts";
import { Mutex } from "./mutex.ts";

Expand Down
Loading

0 comments on commit f61dbcb

Please sign in to comment.