ForgeTotal.js 5
hu

Total.js 5

Néhány munkaszál megosztása a NEWTHREADPOOL()-lal

Total.js 5 · total5@0.0.19 workerthreadpoolperformance Total.js 5-tel lefuttatva

A NEWTHREAD() egy workert indít. Ha sok kérésnek ugyanarra a nehéz munkára van szüksége, kérésenként egy worker túl sok, egyetlen worker pedig sorrend nélkül egymásra várakoztatja őket. A NEWTHREADPOOL(name, count, [isfork]) count workert indít a workers/name.js fájlból (egy szálat; ha az isfork értéke true, gyermekfolyamatot, mint a NEWFORK()), és egyenként osztja ki őket.

  • A pool.exec(function(worker, release) {}) megvárja, amíg egy worker szabad, és meghívja vele a függvényét. Küldje el neki a munkát a worker.postMessage(value)-val, olvassa a választ a worker.once('message', fn)-nel, és hívja meg a release()-t, ha végzett: a worker visszatér a poolba, és a következő várakozó feladat átveszi.
  • Függvény nélkül a pool.exec() egy promise-t ad vissza, amely a worker-rel teljesül (és a workernek van worker.release()-e), így await-tel is működik.
  • A feladatokat a kérés sorrendjében szolgálja ki. A pool nem sorba állítja a worker üzeneteit: egyszerre egy feladat birtokolja.
  • A pool az F.workers[name]-ben is megmarad. A pool.workers a workerek listája.

A worker fájlja ugyanaz, mint a NEWTHREAD() esetében: benne a NEWTHREAD() a worker.message és worker.postMessage() kezelőt adja vissza. Itt minden worker összeadja a számokat, és megmondja, melyik szál végezte.

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