ForgeTotal.js 5
el

Total.js 5

Μοιραστείτε μερικά νήματα εργασίας με το NEWTHREADPOOL()

Total.js 5 · total5@0.0.19 workerthreadpoolperformance Εκτελέστηκε με το Total.js 5

Το NEWTHREAD() ξεκινά έναν worker. Όταν πολλά αιτήματα χρειάζονται την ίδια βαριά εργασία, ένας worker ανά αίτημα είναι πάρα πολλοί και ένας μόνο worker τα κάνει να περιμένουν το ένα το άλλο χωρίς καμία σειρά. Το NEWTHREADPOOL(name, count, [isfork]) ξεκινά count workers από το workers/name.js (ένα νήμα· με το isfork ίσο με true, μια θυγατρική διεργασία, όπως το NEWFORK()) και τους μοιράζει έναν έναν.

  • Το pool.exec(function(worker, release) {}) περιμένει μέχρι να υπάρξει ελεύθερος worker και καλεί τη συνάρτησή σας με αυτόν. Στείλτε του τη δουλειά με worker.postMessage(value), διαβάστε την απάντηση με worker.once('message', fn) και καλέστε release() όταν τελειώσετε: ο worker επιστρέφει στο pool και τον παίρνει η επόμενη εργασία που περιμένει.
  • Χωρίς συνάρτηση, το pool.exec() επιστρέφει ένα promise που επιλύεται με worker (και ο worker έχει worker.release()), οπότε λειτουργεί με await.
  • Οι εργασίες εξυπηρετούνται με τη σειρά που ζήτησαν. Το pool δεν βάζει σε ουρά τα μηνύματα ενός worker: μία εργασία τη φορά τον έχει.
  • Το pool κρατιέται και στο F.workers[name]. Το pool.workers είναι η λίστα των workers.

Το αρχείο του worker είναι το ίδιο όπως για το NEWTHREAD(): το NEWTHREAD() μέσα του επιστρέφει τον χειριστή με worker.message και worker.postMessage(). Εδώ κάθε worker αθροίζει τους αριθμούς και λέει ποιο νήμα το έκανε.

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