ForgeTotal.js 5
nl

Total.js 5

Deel een paar worker-threads met NEWTHREADPOOL()

Total.js 5 · total5@0.0.19 workerthreadpoolperformance Uitgevoerd met Total.js 5

NEWTHREAD() start één worker. Als veel verzoeken dezelfde zware taak nodig hebben, zijn het er te veel met een worker per verzoek, en één enkele worker laat ze zonder volgorde op elkaar wachten. NEWTHREADPOOL(name, count, [isfork]) start count workers van workers/name.js (een thread; met isfork op true een kindproces, zoals NEWFORK()) en deelt ze één voor één uit.

  • pool.exec(function(worker, release) {}) wacht tot een worker vrij is en roept je functie ermee aan. Stuur hem het werk met worker.postMessage(value), lees het antwoord met worker.once('message', fn) en roep release() aan als je klaar bent: de worker gaat terug naar de pool en de volgende wachtende taak neemt hem.
  • Zonder functie geeft pool.exec() een promise terug die wordt opgelost met worker (en de worker heeft worker.release()), zodat het met await werkt.
  • De taken worden bediend in de volgorde waarin ze erom vroegen. De pool zet de berichten van een worker niet in de wachtrij: één taak tegelijk heeft hem.
  • De pool wordt ook bewaard in F.workers[name]. pool.workers is de lijst van de workers.

Het workerbestand is hetzelfde als voor NEWTHREAD(): NEWTHREAD() erin geeft de handle terug met worker.message en worker.postMessage(). Hier telt elke worker de getallen op en zegt welke thread het deed.

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