Play with Semaphore
Semaphore represents a generalized mutex, you can think of it as a physical semaphore that manages traffic

Semaphore

1
export interface Semaphore {
2
/**
3
* Acquire a permit, blocking if not all are vailable
4
*/
5
readonly acquire: T.Effect<T.NoEnv, never, void>;
6
/**
7
* Release a permit
8
*/
9
readonly release: T.Effect<T.NoEnv, never, void>;
10
/**
11
* Get the number of available permits
12
*/
13
readonly available: T.Effect<T.NoEnv, never, number>;
14
15
/**
16
* Acquire multiple permits blocking if not all are available
17
* @param n
18
*/
19
acquireN(n: number): T.Effect<T.NoEnv, never, void>;
20
/**
21
* Release mutliple permits
22
* @param n
23
*/
24
releaseN(n: number): T.Effect<T.NoEnv, never, void>;
25
/**
26
* Bracket the given io with acquireN/releaseN calls
27
* @param n
28
* @param io
29
*/
30
withPermitsN<R, E, A>(n: number, io: T.Effect<R, E, A>): T.Effect<R, E, A>;
31
/**
32
* withPermitN(1, _)
33
* @param n
34
*/
35
withPermit<R, E, A>(n: T.Effect<R, E, A>): T.Effect<R, E, A>;
36
}
37
38
/**
39
* Allocate a semaphore.
40
*
41
* @param n the number of permits
42
* This must be non-negative
43
*/
44
export function makeSemaphore(n: number): T.Effect<T.NoEnv, never, Semaphore> {
45
return T.applySecond(
46
sanityCheck(n),
47
effect.map(makeRef(right(n) as State), makeSemaphoreImpl)
48
);
49
}
Copied!

Usage

1
import { effect as T, semaphore as S, exit as E } from "@matechs/effect";
2
import { Do } from "fp-ts-contrib/lib/Do";
3
import * as A from "fp-ts/lib/Array";
4
5
const program = Do(T.effect)
6
.bind("sem", S.makeSemaphore(10)) // create a semaphore with 10 permits
7
.bindL("res", ({ sem }) =>
8
// this uses parallel instances and concurrency is limited at 10
9
A.array.traverse(T.parEffect)(A.range(1, 10000), n =>
10
sem.withPermit(T.pure(n + 1)) // use a permit to run op
11
)
12
)
13
.return(s => s.res);
14
15
T.run(
16
program,
17
E.fold(
18
arr => {
19
console.log(arr.length); // prints 10000
20
},
21
console.error, // raised
22
console.error, // abort
23
() => {
24
console.error("interrupted");
25
}
26
)
27
);
Copied!
Last modified 1yr ago
Copy link