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 | ||
479ba9f6 JB |
81 | export const executeAsyncFn = async fn => { |
82 | try { | |
83 | await fn() | |
84 | } catch (e) { | |
85 | console.error(e) | |
86 | // eslint-disable-next-line n/no-process-exit | |
87 | process.exit(1) | |
88 | } | |
89 | } | |
90 | ||
bac873bd JB |
91 | export const generateRandomInteger = ( |
92 | max = Number.MAX_SAFE_INTEGER, | |
93 | min = 0 | |
94 | ) => { | |
548140e6 | 95 | if (max < min || max < 0 || min < 0) { |
4af5c11a JB |
96 | throw new RangeError('Invalid interval') |
97 | } | |
c2d7d79b | 98 | max = Math.floor(max) |
4af5c11a | 99 | if (min != null && min !== 0) { |
c2d7d79b | 100 | min = Math.ceil(min) |
872585ea | 101 | return Math.floor(Math.random() * (max - min + 1)) + min |
74750c7f | 102 | } |
872585ea | 103 | return Math.floor(Math.random() * (max + 1)) |
74750c7f JB |
104 | } |
105 | ||
041dc05b | 106 | const jsonIntegerSerialization = n => { |
cdace0e5 JB |
107 | for (let i = 0; i < n; i++) { |
108 | const o = { | |
109 | a: i | |
110 | } | |
111 | JSON.stringify(o) | |
112 | } | |
30b963d4 | 113 | return { ok: 1 } |
cdace0e5 JB |
114 | } |
115 | ||
bdacc2d2 JB |
116 | /** |
117 | * Intentionally inefficient implementation. | |
7d82d90e JB |
118 | * @param {number} n - The number of fibonacci numbers to generate. |
119 | * @returns {number} - The nth fibonacci number. | |
bdacc2d2 | 120 | */ |
041dc05b | 121 | const fibonacci = n => { |
024daf59 | 122 | if (n <= 1) return n |
bdacc2d2 JB |
123 | return fibonacci(n - 1) + fibonacci(n - 2) |
124 | } | |
125 | ||
7d82d90e JB |
126 | /** |
127 | * Intentionally inefficient implementation. | |
7d82d90e JB |
128 | * @param {number} n - The number to calculate the factorial of. |
129 | * @returns {number} - The factorial of n. | |
130 | */ | |
041dc05b | 131 | const factorial = n => { |
7d82d90e JB |
132 | if (n === 0) { |
133 | return 1 | |
7d82d90e | 134 | } |
965415bb | 135 | return factorial(n - 1) * n |
7d82d90e JB |
136 | } |
137 | ||
bac873bd | 138 | const readWriteFiles = ( |
670734fc JB |
139 | n, |
140 | baseDirectory = `/tmp/poolifier-benchmarks/${crypto.randomInt( | |
141 | 281474976710655 | |
142 | )}` | |
bac873bd | 143 | ) => { |
670734fc JB |
144 | if (fs.existsSync(baseDirectory) === true) { |
145 | fs.rmSync(baseDirectory, { recursive: true }) | |
cdace0e5 | 146 | } |
670734fc | 147 | fs.mkdirSync(baseDirectory, { recursive: true }) |
cdace0e5 JB |
148 | for (let i = 0; i < n; i++) { |
149 | const filePath = `${baseDirectory}/${i}` | |
150 | fs.writeFileSync(filePath, i.toString(), { | |
151 | encoding: 'utf8', | |
152 | flag: 'a' | |
153 | }) | |
154 | fs.readFileSync(filePath, 'utf8') | |
155 | } | |
670734fc | 156 | fs.rmSync(baseDirectory, { recursive: true }) |
30b963d4 | 157 | return { ok: 1 } |
cdace0e5 JB |
158 | } |
159 | ||
041dc05b | 160 | export const executeTaskFunction = data => { |
2d2e32c2 | 161 | switch (data.function) { |
dbca3be9 | 162 | case TaskFunctions.jsonIntegerSerialization: |
d1a9aa41 | 163 | return jsonIntegerSerialization(data.taskSize || 1000) |
dbca3be9 | 164 | case TaskFunctions.fibonacci: |
d1a9aa41 | 165 | return fibonacci(data.taskSize || 1000) |
dbca3be9 | 166 | case TaskFunctions.factorial: |
d1a9aa41 | 167 | return factorial(data.taskSize || 1000) |
dbca3be9 | 168 | case TaskFunctions.readWriteFiles: |
cdace0e5 | 169 | return readWriteFiles(data.taskSize || 1000) |
2d2e32c2 | 170 | default: |
dbca3be9 | 171 | throw new Error('Unknown task function') |
2d2e32c2 JB |
172 | } |
173 | } |