ForgeTotal.js 5
cs

Total.js 5

Sdílejte několik pracovních vláken pomocí NEWTHREADPOOL()

Total.js 5 · total5@0.0.19 workerthreadpoolperformance Spuštěno s Total.js 5

NEWTHREAD() spustí jednoho workera. Když mnoho požadavků potřebuje tutéž náročnou úlohu, worker na každý požadavek je příliš mnoho a jediný worker je nutí čekat jeden na druhého bez jakéhokoli pořadí. NEWTHREADPOOL(name, count, [isfork]) spustí count workerů z workers/name.js (vlákno; s isfork nastaveným na true podproces, jako NEWFORK()) a rozdává je po jednom.

  • pool.exec(function(worker, release) {}) počká, až je worker volný, a zavolá vaši funkci s ním. Pošlete mu práci přes worker.postMessage(value), odpověď přečtěte přes worker.once('message', fn) a až skončíte, zavolejte release(): worker se vrátí do poolu a převezme jej další čekající úloha.
  • Bez funkce pool.exec() vrátí promise, který se vyřeší s worker (a worker má worker.release()), takže funguje s await.
  • Úlohy se obsluhují v pořadí, v jakém o workera požádaly. Pool neřadí zprávy workera do fronty: v jednu chvíli jej má jedna úloha.
  • Pool je uložen i v F.workers[name]. pool.workers je seznam workerů.

Soubor workera je stejný jako u NEWTHREAD(): NEWTHREAD() v něm vrátí handle s worker.message a worker.postMessage(). Zde každý worker sečte čísla a řekne, které vlákno to udělalo.

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