ForgeTotal.js 5
de

Total.js 5

Einige Worker-Threads mit NEWTHREADPOOL() teilen

Total.js 5 · total5@0.0.19 workerthreadpoolperformance Mit Total.js 5 ausgeführt

NEWTHREAD() startet einen Worker. Wenn viele Anfragen dieselbe schwere Aufgabe brauchen, sind ein Worker pro Anfrage zu viele, und ein einzelner Worker lässt sie ohne Reihenfolge aufeinander warten. NEWTHREADPOOL(name, count, [isfork]) startet count Worker aus workers/name.js (ein Thread; mit isfork auf true ein Kindprozess, wie bei NEWFORK()) und gibt sie einzeln aus.

  • pool.exec(function(worker, release) {}) wartet, bis ein Worker frei ist, und ruft deine Funktion mit ihm auf. Sende ihm die Arbeit mit worker.postMessage(value), lies die Antwort mit worker.once('message', fn) und rufe release() auf, wenn du fertig bist: Der Worker geht zurück in den Pool, und die nächste wartende Aufgabe übernimmt ihn.
  • Ohne Funktion gibt pool.exec() ein Promise zurück, das mit worker aufgelöst wird (und der Worker hat worker.release()), sodass es mit await funktioniert.
  • Die Aufgaben werden in der Reihenfolge bedient, in der sie gefragt haben. Der Pool reiht die Nachrichten eines Workers nicht ein: Jeweils eine Aufgabe hat ihn.
  • Der Pool wird auch in F.workers[name] gehalten. pool.workers ist die Liste der Worker.

Die Worker-Datei ist dieselbe wie für NEWTHREAD(): NEWTHREAD() darin gibt das Handle mit worker.message und worker.postMessage() zurück. Hier addiert jeder Worker die Zahlen und sagt, welcher Thread es getan hat.

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