| /*--------------------------------------------------------- |
| * Copyright 2021 The Go Authors. All rights reserved. |
| * Licensed under the MIT License. See LICENSE in the project root for license information. |
| *--------------------------------------------------------*/ |
| |
| import assert from 'assert'; |
| import { Mutex } from '../../src/utils/mutex'; |
| |
| suite('Mutex Tests', () => { |
| test('works for basic concurrent access', async () => { |
| const m = new Mutex(); |
| |
| let cnt = 0; |
| const worker = async (delay: number, count: number) => { |
| for (let i = 0; i < count; i++) { |
| const unlock = await m.lock(); |
| try { |
| const cntCopy = cnt; |
| await sleep(delay); |
| cnt = cntCopy + 1; |
| } finally { |
| unlock(); |
| } |
| } |
| }; |
| |
| await Promise.all([worker(3, 5), worker(1, 10)]); |
| assert.strictEqual(cnt, 15); |
| }); |
| |
| test('works when lock holders throw errors', async () => { |
| const m = new Mutex(); |
| |
| let cnt = 0; |
| const worker = async (delay: number) => { |
| const unlock = await m.lock(); |
| try { |
| const cntCopy = cnt; |
| await sleep(delay); |
| cnt = cntCopy + 1; |
| throw new Error('ooops'); |
| } finally { |
| unlock(); |
| } |
| }; |
| |
| const safeWorker = async (delay: number) => { |
| try { |
| await worker(delay); |
| } catch (e) { |
| // swallow the exception |
| } |
| }; |
| |
| await Promise.all([safeWorker(3), safeWorker(2), safeWorker(1), safeWorker(0)]); |
| assert.strictEqual(cnt, 4); |
| }); |
| }); |
| |
| function sleep(ms: number) { |
| return new Promise((resolve) => setTimeout(resolve, ms)); |
| } |