Skip to content

Migration (v1 to v2)

Λlisue (Ali sue・ありすえ) edited this page May 5, 2023 · 1 revision

Migration from v1 to v2

Lock

Use lock() method instead of with().

v1

import { Lock } from "https://deno.land/x/[email protected]/mod.ts";
import { delay } from "https://deno.land/[email protected]/async/mod.ts";

const lock = new Lock();

const task1 = async () => {
  await lock.with(async () => {
    await delay(50);
    console.log("Task1 start");
    await delay(100);
    console.log("Task1 end");
  });
};

const task2 = async () => {
  await lock.with(async () => {
    await delay(10);
    console.log("Task2 start");
    await delay(10);
    console.log("Task2 end");
  });
};

const task3 = async () => {
  await lock.with(async () => {
    console.log("Task3 start");
    await delay(50);
    console.log("Task3 end");
  });
};

await Promise.all([task1(), task2(), task3()]);
// Task1 start
// Task1 end
// Task2 start
// Task2 end
// Task3 start
// Task3 end

v2

import { Lock } from "https://deno.land/x/async/lock.ts";
import { delay } from "https://deno.land/[email protected]/async/mod.ts";

const lock = new Lock(undefined);

const task1 = async () => {
  await lock.lock(async () => {
    await delay(50);
    console.log("Task1 start");
    await delay(100);
    console.log("Task1 end");
  });
};

const task2 = async () => {
  await lock.lock(async () => {
    await delay(10);
    console.log("Task2 start");
    await delay(10);
    console.log("Task2 end");
  });
};

const task3 = async () => {
  await lock.lock(async () => {
    console.log("Task3 start");
    await delay(50);
    console.log("Task3 end");
  });
};

await Promise.all([task1(), task2(), task3()]);
// Task1 start
// Task1 end
// Task2 start
// Task2 end
// Task3 start
// Task3 end

Event

Create a Deferred with the official deferred function.

v1

import { Event } from "https://deno.land/x/[email protected]/mod.ts";
import { delay } from "https://deno.land/[email protected]/async/mod.ts";

const event = new Event();

const task1 = async () => {
  await event.wait();
  console.log("Task1 complete");
};

const task2 = async () => {
  await event.wait();
  console.log("Task2 complete");
};

const task3 = async () => {
  await delay(100);
  console.log("Hello");
  event.set();
  await delay(100);
  console.log("World");
};

await Promise.all([task1(), task2(), task3()]);
// Hello
// Task1 complete
// Task2 complete
// World
and use it instead.

v2

import { deferred, delay } from "https://deno.land/[email protected]/async/mod.ts";

const event = deferred<void>();

const task1 = async () => {
  await event;
  console.log("Task1 complete");
};

const task2 = async () => {
  await event;
  console.log("Task2 complete");
};

const task3 = async () => {
  await delay(100);
  console.log("Hello");
  event.resolve();
  await delay(100);
  console.log("World");
};

await Promise.all([task1(), task2(), task3()]);
// Hello
// Task1 complete
// Task2 complete
// World

Condition

Use Notify to notify waiters instead of Condition.

v1

import { Condition } from "https://deno.land/x/[email protected]/mod.ts";
import { delay } from "https://deno.land/[email protected]/async/mod.ts";

const cond = new Condition();
let counter = 0;

const countUp = () => {
  cond.with(() => {
    counter += 1;
    console.log("Count up");
    cond.notify();
    console.log("Notified");
  });
};

const task1 = async () => {
  await cond.with(async () => {
    await cond.wait();
    console.log("Task1 complete");
  });
};

const task2 = async () => {
  await cond.with(async () => {
    await cond.wait_for(() => counter >= 3);
    console.log("Task2 complete");
  });
};

const task3 = async () => {
  await delay(100);
  countUp();
  await delay(100);
  countUp();
  await delay(100);
  countUp();
  await delay(100);
  countUp();
  await delay(100);
  countUp();
};

await Promise.all([task1(), task2(), task3()]);
// Count up
// Notified
// Task1 complete
// Count up
// Notified
// Count up
// Notified
// Task2 complete
// Count up
// Notified
// Count up
// Notified

v2

import { Notify } from "https://deno.land/x/async/notify.ts";
import { delay } from "https://deno.land/[email protected]/async/mod.ts";

const notify = new Notify();
let counter = 0;

const countUp = () => {
  counter += 1;
  console.log("Count up");
  notify.notify();
  console.log("Notified");
};

const task1 = async () => {
  await notify.notified();
  console.log("Task1 complete");
};

const task2 = async () => {
  while (counter < 3) {
    await notify.notified();
  }
  console.log("Task2 complete");
};

const task3 = async () => {
  await delay(100);
  countUp();
  await delay(100);
  countUp();
  await delay(100);
  countUp();
  await delay(100);
  countUp();
  await delay(100);
  countUp();
};

await Promise.all([task1(), task2(), task3()]);
// Count up
// Notified
// Task1 complete
// Count up
// Notified
// Count up
// Notified
// Task2 complete
// Count up
// Notified
// Count up
// Notified

Semaphore

Use lock() method instead of with().

v1

import { Semaphore } from "https://deno.land/x/[email protected]/mod.ts";
import { delay } from "https://deno.land/[email protected]/async/mod.ts";

const sem = new Semaphore(3);
let n_workers = 0;

const worker = async () => {
  await sem.with(async () => {
    n_workers += 1;
    console.log(`${n_workers} workers are working...`);
    await delay(100);
    console.log(`Complete`);
    n_workers -= 1;
  });
};

const workers = [
  worker(),
  worker(),
  worker(),
  worker(),
  worker(),
  worker(),
  worker(),
  worker(),
  worker(),
  worker(),
];
await Promise.all(workers);
// 1 workers are working...
// 2 workers are working...
// 3 workers are working...
// Complete
// 3 workers are working...
// Complete
// 3 workers are working...
// Complete
// 3 workers are working...
// Complete
// 3 workers are working...
// Complete
// 3 workers are working...
// Complete
// 3 workers are working...
// Complete
// 3 workers are working...
// Complete
// Complete
// Complete

v2

import { Semaphore } from "https://deno.land/x/async/mod.ts";
import { delay } from "https://deno.land/[email protected]/async/mod.ts";

const sem = new Semaphore(3);
let n_workers = 0;

const worker = async () => {
  await sem.lock(async () => {
    n_workers += 1;
    console.log(`${n_workers} workers are working...`);
    await delay(100);
    console.log(`Complete`);
    n_workers -= 1;
  });
};

const workers = [
  worker(),
  worker(),
  worker(),
  worker(),
  worker(),
  worker(),
  worker(),
  worker(),
  worker(),
  worker(),
];
await Promise.all(workers);
// 1 workers are working...
// 2 workers are working...
// 3 workers are working...
// Complete
// 3 workers are working...
// Complete
// 3 workers are working...
// Complete
// 3 workers are working...
// Complete
// 3 workers are working...
// Complete
// 3 workers are working...
// Complete
// 3 workers are working...
// Complete
// 3 workers are working...
// Complete
// Complete
// Complete

Queue

Use pop() and push() method instead of get() and put().

v1

import { Queue } from "https://deno.land/x/[email protected]/mod.ts";
import { deferred, delay } from "https://deno.land/[email protected]/async/mod.ts";

const queue: Queue<string> = new Queue();
const closed = deferred<true>();

const consumer = async () => {
  while (true) {
    const recv = await Promise.race([queue.get(), closed]);
    if (recv === true) {
      break;
    }
    console.log(`Recv: ${recv}`);
  }
};

const producer = async () => {
  await delay(100);
  await queue.put("Hello");
  await delay(100);
  await queue.put("World");
  await delay(100);
  closed.resolve(true);
};

await Promise.all([consumer(), producer()]);
// Recv: Hello
// Recv: World

v2

import { Queue } from "https://deno.land/x/async/queue.ts";
import { deferred, delay } from "https://deno.land/[email protected]/async/mod.ts";

const queue: Queue<string> = new Queue();
const closed = deferred<true>();

const consumer = async () => {
  while (true) {
    const recv = await Promise.race([queue.pop(), closed]);
    if (recv === true) {
      break;
    }
    console.log(`Recv: ${recv}`);
  }
};

const producer = async () => {
  await delay(100);
  await queue.push("Hello");
  await delay(100);
  await queue.push("World");
  await delay(100);
  closed.resolve(true);
};

await Promise.all([consumer(), producer()]);
// Recv: Hello
// Recv: World
Clone this wiki locally