Skip to content

Instantly share code, notes, and snippets.

@bseib
Created February 29, 2020 15:04
Show Gist options
  • Save bseib/3e0ed388e0ce9fff1c221d697052ae40 to your computer and use it in GitHub Desktop.
Save bseib/3e0ed388e0ce9fff1c221d697052ae40 to your computer and use it in GitHub Desktop.
CountDownLatch in typescript
import {describe, it} from 'mocha';
import {equal, throws } from 'assert';
import { CountDownLatch } from './CountDownLatch';
describe('CountDownLatch usage suite', () => {
it('fails correctly with a negative starting count', () => {
throws(() => {
new CountDownLatch(-1);
}, 'should have thrown an error with a negative start count');
});
it('counts down from 1 correctly', (done: Mocha.Done) => {
const latch = new CountDownLatch(1);
equal(latch.count, 1);
latch.onZero().then(() => {
equal(latch.count, 0);
done();
});
setTimeout(() => {
latch.countDown();
}, 100);
equal(latch.count, 1);
});
it('counts down from 3 correctly', (done: Mocha.Done) => {
const latch = new CountDownLatch(3);
equal(latch.count, 3);
latch.onZero().then(() => {
equal(latch.count, 0);
done();
});
setTimeout(() => {
latch.countDown();
equal(latch.count, 2);
}, 100);
setTimeout(() => {
latch.countDown();
equal(latch.count, 1);
}, 200);
setTimeout(() => {
latch.countDown();
equal(latch.count, 0);
}, 300);
setTimeout(() => {
latch.countDown();
// does not go below zero
equal(latch.count, 0);
}, 400);
equal(latch.count, 3);
});
});
export class CountDownLatch {
private _count: number;
private _onZeroPromise: Promise<void>;
private _reachedZero: ((value?: void | PromiseLike<void> | undefined) => void) | undefined;
constructor(count: number) {
if ( count < 0 ) {
throw new Error('count cannot be negative');
}
this._count = count;
this._onZeroPromise = new Promise((resolve) => {
this._reachedZero = resolve;
});
}
public countDown() {
if ( this._count > 0 ) {
this._count -= 1;
if ( this._count == 0 && undefined != this._reachedZero ) {
this._reachedZero();
}
}
}
public onZero(): Promise<void> {
return this._onZeroPromise;
}
public get count() {
return this._count;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment