# Împarte câteva fire de lucru cu NEWTHREADPOOL()

> Pornește un număr fix de workeri, împrumută unul cu pool.exec() când există de lucru, dă-l înapoi cu release() și lasă celelalte sarcini să aștepte un worker liber.

Framework: total5
Product: Total.js 5 (total5@0.0.19)
Language: ro
Content-SHA256: dbb3ff6356f42b4f136fa28b3d667aa822ee48660abe95bcc163e2a53162618f
Snapshot: c0700e321579725c5cf4f5ace1ad7d2866d1b4f93c24a63c0b41b6b7998e976c
Sources: total5-installed@total5@0.0.19
Review: not-recorded

`NEWTHREAD()` pornește un worker. Când multe cereri au nevoie de aceeași muncă grea, un worker pe cerere este prea mult, iar un singur worker le face să se aștepte unele pe altele fără nicio ordine. `NEWTHREADPOOL(name, count, [isfork])` pornește `count` workeri din `workers/<name>.js` (un fir; cu `isfork` setat la `true`, un proces copil, ca `NEWFORK()`) și îi distribuie pe rând.

- `pool.exec(function(worker, release) {})` așteaptă până când un worker este liber și apelează funcția ta cu el. Trimite-i munca cu `worker.postMessage(value)`, citește răspunsul cu `worker.once('message', fn)` și **apelează `release()` când ai terminat**: workerul se întoarce în pool, iar următoarea sarcină care așteaptă îl preia.
- Fără funcție, `pool.exec()` returnează o promisiune care se rezolvă cu `worker` (iar workerul are `worker.release()`), deci funcționează cu `await`.
- Sarcinile sunt servite în ordinea în care au cerut. Pool-ul nu pune în coadă mesajele unui worker: o singură sarcină îl are la un moment dat.
- Pool-ul este păstrat și în `F.workers[name]`. `pool.workers` este lista workerilor.

Fișierul workerului este același ca pentru `NEWTHREAD()`: `NEWTHREAD()` în interiorul lui returnează handle-ul cu `worker.message` și `worker.postMessage()`. Aici fiecare worker adună numerele și spune ce fir a făcut-o.

```js workers/total.js
require('total5');

const worker = NEWTHREAD();

worker.message = function(message) {
	let total = 0;
	for (let i = 1; i <= message.to; i++)
		total += i;
	worker.postMessage({ to: message.to, total: total, thread: require('worker_threads').threadId });
};
```

```js controllers/total.js
exports.install = function() {
	ROUTE('GET /total/{to}/', total);
	ROUTE('GET /await/{to}/', total_await);
	ROUTE('GET /workers/', workers);
};

const pool = NEWTHREADPOOL('total', 2);

function total($) {
	pool.exec(function(worker, release) {
		worker.once('message', function(response) {
			release();
			$.json(response);
		});
		worker.postMessage({ to: +$.params.to });
	});
}

async function total_await($) {
	const worker = await pool.exec();
	worker.once('message', function(response) {
		worker.release();
		$.json(response);
	});
	worker.postMessage({ to: +$.params.to });
}

function workers($) {
	$.json({ workers: pool.workers.length, registered: F.workers.total === pool });
}
```
