| /*--------------------------------------------------------- | |
| * 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 { | |
| // 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)); | |
| } |