Commit | Line | Data |
---|---|---|
d5fdc57b JB |
1 | import crypto from 'node:crypto' |
2 | import fs from 'node:fs' | |
8f810074 | 3 | import { |
cdace0e5 JB |
4 | DynamicClusterPool, |
5 | DynamicThreadPool, | |
6 | FixedClusterPool, | |
d9d8c14e JB |
7 | FixedThreadPool, |
8 | PoolTypes, | |
9 | WorkerTypes | |
8f810074 | 10 | } from '../lib/index.mjs' |
dbca3be9 | 11 | import { TaskFunctions } from './benchmarks-types.mjs' |
2d2e32c2 | 12 | |
479ba9f6 JB |
13 | export const buildPoolifierPool = ( |
14 | workerType, | |
15 | poolType, | |
16 | poolSize, | |
17 | poolOptions | |
18 | ) => { | |
19 | switch (poolType) { | |
20 | case PoolTypes.fixed: | |
21 | switch (workerType) { | |
22 | case WorkerTypes.thread: | |
23 | return new FixedThreadPool( | |
24 | poolSize, | |
25 | './benchmarks/internal/thread-worker.mjs', | |
26 | poolOptions | |
27 | ) | |
28 | case WorkerTypes.cluster: | |
29 | return new FixedClusterPool( | |
30 | poolSize, | |
31 | './benchmarks/internal/cluster-worker.mjs', | |
32 | poolOptions | |
33 | ) | |
34 | } | |
35 | break | |
36 | case PoolTypes.dynamic: | |
37 | switch (workerType) { | |
38 | case WorkerTypes.thread: | |
39 | return new DynamicThreadPool( | |
40 | Math.floor(poolSize / 2), | |
41 | poolSize, | |
42 | './benchmarks/internal/thread-worker.mjs', | |
43 | poolOptions | |
44 | ) | |
45 | case WorkerTypes.cluster: | |
46 | return new DynamicClusterPool( | |
47 | Math.floor(poolSize / 2), | |
48 | poolSize, | |
49 | './benchmarks/internal/cluster-worker.mjs', | |
50 | poolOptions | |
51 | ) | |
52 | } | |
53 | break | |
54 | } | |
55 | } | |
56 | ||
57 | export const runPoolifierTest = async ( | |
58 | pool, | |
59 | { taskExecutions, workerData } | |
60 | ) => { | |
ff5e76e1 JB |
61 | return new Promise((resolve, reject) => { |
62 | let executions = 0 | |
cdace0e5 | 63 | for (let i = 1; i <= taskExecutions; i++) { |
ff5e76e1 JB |
64 | pool |
65 | .execute(workerData) | |
fe2f6f84 | 66 | .then(() => { |
0762fbb1 | 67 | ++executions |
cdace0e5 | 68 | if (executions === taskExecutions) { |
ca6c7d70 | 69 | return resolve({ ok: 1 }) |
ff5e76e1 JB |
70 | } |
71 | return null | |
72 | }) | |
041dc05b | 73 | .catch(err => { |
23ff945a JB |
74 | console.error(err) |
75 | return reject(err) | |
76 | }) | |
ff5e76e1 JB |
77 | } |
78 | }) | |
79 | } | |
80 | ||
a7825346 JB |
81 | export const getPoolImplementationName = pool => { |
82 | if (pool instanceof FixedThreadPool) { | |
83 | return 'FixedThreadPool' | |
84 | } else if (pool instanceof DynamicThreadPool) { | |
85 | return 'DynamicThreadPool' | |
86 | } else if (pool instanceof FixedClusterPool) { | |
87 | return 'FixedClusterPool' | |
88 | } else if (pool instanceof DynamicClusterPool) { | |
89 | return 'DynamicClusterPool' | |
90 | } | |
91 | } | |
92 | ||
f1c674cd JB |
93 | export const LIST_FORMATTER = new Intl.ListFormat('en-US', { |
94 | style: 'long', | |
95 | type: 'conjunction' | |
96 | }) | |
97 | ||
479ba9f6 JB |
98 | export const executeAsyncFn = async fn => { |
99 | try { | |
100 | await fn() | |
101 | } catch (e) { | |
102 | console.error(e) | |
103 | // eslint-disable-next-line n/no-process-exit | |
104 | process.exit(1) | |
105 | } | |
106 | } | |
107 | ||
bac873bd JB |
108 | export const generateRandomInteger = ( |
109 | max = Number.MAX_SAFE_INTEGER, | |
110 | min = 0 | |
111 | ) => { | |
548140e6 | 112 | if (max < min || max < 0 || min < 0) { |
4af5c11a JB |
113 | throw new RangeError('Invalid interval') |
114 | } | |
c2d7d79b | 115 | max = Math.floor(max) |
4af5c11a | 116 | if (min != null && min !== 0) { |
c2d7d79b | 117 | min = Math.ceil(min) |
872585ea | 118 | return Math.floor(Math.random() * (max - min + 1)) + min |
74750c7f | 119 | } |
872585ea | 120 | return Math.floor(Math.random() * (max + 1)) |
74750c7f JB |
121 | } |
122 | ||
041dc05b | 123 | const jsonIntegerSerialization = n => { |
cdace0e5 JB |
124 | for (let i = 0; i < n; i++) { |
125 | const o = { | |
126 | a: i | |
127 | } | |
128 | JSON.stringify(o) | |
129 | } | |
30b963d4 | 130 | return { ok: 1 } |
cdace0e5 JB |
131 | } |
132 | ||
bdacc2d2 JB |
133 | /** |
134 | * Intentionally inefficient implementation. | |
7d82d90e JB |
135 | * @param {number} n - The number of fibonacci numbers to generate. |
136 | * @returns {number} - The nth fibonacci number. | |
bdacc2d2 | 137 | */ |
041dc05b | 138 | const fibonacci = n => { |
024daf59 | 139 | if (n <= 1) return n |
bdacc2d2 JB |
140 | return fibonacci(n - 1) + fibonacci(n - 2) |
141 | } | |
142 | ||
7d82d90e JB |
143 | /** |
144 | * Intentionally inefficient implementation. | |
7d82d90e JB |
145 | * @param {number} n - The number to calculate the factorial of. |
146 | * @returns {number} - The factorial of n. | |
147 | */ | |
041dc05b | 148 | const factorial = n => { |
7d82d90e JB |
149 | if (n === 0) { |
150 | return 1 | |
7d82d90e | 151 | } |
965415bb | 152 | return factorial(n - 1) * n |
7d82d90e JB |
153 | } |
154 | ||
bac873bd | 155 | const readWriteFiles = ( |
670734fc JB |
156 | n, |
157 | baseDirectory = `/tmp/poolifier-benchmarks/${crypto.randomInt( | |
158 | 281474976710655 | |
159 | )}` | |
bac873bd | 160 | ) => { |
670734fc JB |
161 | if (fs.existsSync(baseDirectory) === true) { |
162 | fs.rmSync(baseDirectory, { recursive: true }) | |
cdace0e5 | 163 | } |
670734fc | 164 | fs.mkdirSync(baseDirectory, { recursive: true }) |
cdace0e5 JB |
165 | for (let i = 0; i < n; i++) { |
166 | const filePath = `${baseDirectory}/${i}` | |
167 | fs.writeFileSync(filePath, i.toString(), { | |
168 | encoding: 'utf8', | |
169 | flag: 'a' | |
170 | }) | |
171 | fs.readFileSync(filePath, 'utf8') | |
172 | } | |
670734fc | 173 | fs.rmSync(baseDirectory, { recursive: true }) |
30b963d4 | 174 | return { ok: 1 } |
cdace0e5 JB |
175 | } |
176 | ||
041dc05b | 177 | export const executeTaskFunction = data => { |
2d2e32c2 | 178 | switch (data.function) { |
dbca3be9 | 179 | case TaskFunctions.jsonIntegerSerialization: |
d1a9aa41 | 180 | return jsonIntegerSerialization(data.taskSize || 1000) |
dbca3be9 | 181 | case TaskFunctions.fibonacci: |
d1a9aa41 | 182 | return fibonacci(data.taskSize || 1000) |
dbca3be9 | 183 | case TaskFunctions.factorial: |
d1a9aa41 | 184 | return factorial(data.taskSize || 1000) |
dbca3be9 | 185 | case TaskFunctions.readWriteFiles: |
cdace0e5 | 186 | return readWriteFiles(data.taskSize || 1000) |
2d2e32c2 | 187 | default: |
dbca3be9 | 188 | throw new Error('Unknown task function') |
2d2e32c2 JB |
189 | } |
190 | } |