/
kochkatech
/
CorpGame
Обзор
Документация
Войти
/
kochkatech
/
CorpGame
Код
Запросы
1
Задачи
Вики
Пакеты
0
Релизы
1
CI/CD
Аналитика
dev
backend/src/common/keyed-mutex.spec.ts
90 строк
3 KB
kochkareal
feat(devops): свод к одному процессу Node на SQLite, портативная сборка без Docker; аудит безопасности
06 авг 2026, 15:06
06 авг 2026, 15:06
3266bcd
Код
Авторство
О чём код?
import { KeyedMutex } from './keyed-mutex'; /** Хелпер: отдать управление циклу событий, чтобы «параллельные» ветки успели продвинуться. */ const tick = () => new Promise((r) => setImmediate(r)); describe('KeyedMutex', () => { it('не даёт двум держателям одного ключа оказаться в критической секции одновременно', async () => { const mutex = new KeyedMutex(); const log: string[] = []; const first = (async () => { const release = await mutex.acquire('team-a'); log.push('first:enter'); await tick(); log.push('first:exit'); release(); })(); const second = (async () => { const release = await mutex.acquire('team-a'); log.push('second:enter'); release(); })(); await Promise.all([first, second]); expect(log).toEqual(['first:enter', 'first:exit', 'second:enter']); }); it('соблюдает порядок FIFO в очереди на один ключ', async () => { const mutex = new KeyedMutex(); const entered: number[] = []; const workers = [1, 2, 3].map((n) => (async () => { const release = await mutex.acquire('team-a'); entered.push(n); await tick(); release(); })(), ); await Promise.all(workers); expect(entered).toEqual([1, 2, 3]); }); it('разные ключи не блокируют друг друга', async () => { const mutex = new KeyedMutex(); const releaseA = await mutex.acquire('team-a'); // Ключ b свободен — захват обязан пройти, не дожидаясь освобождения a. let acquiredB = false; const pending = mutex.acquire('team-b').then((release) => { acquiredB = true; release(); }); await pending; expect(acquiredB).toBe(true); releaseA(); }); it('освобождает ключ, даже если критическая секция бросила исключение', async () => { const mutex = new KeyedMutex(); await expect( (async () => { const release = await mutex.acquire('team-a'); try { throw new Error('упало внутри'); } finally { release(); } })(), ).rejects.toThrow('упало внутри'); // Если бы лок не отпустили, этот захват завис бы навсегда. const release = await mutex.acquire('team-a'); release(); }); it('не копит записи в Map после того, как очередь опустела', async () => { const mutex = new KeyedMutex(); for (const key of ['a', 'b', 'c']) { const release = await mutex.acquire(key); release(); } await tick(); expect(mutex.size).toBe(0); }); });