ForgeTotal.js 5
ro

Total.js 5

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

Total.js 5 · total5@0.0.19 workerthreadpoolperformance Executată cu Total.js 5

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.

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 });
};
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 });
}