I am trying to implement a basic matrix multiplication using worker threads with a limit of 10 threads. But the threads which are not worker threads are not responding at all.
Matrix A and B are filled with random number generator.
if (isMainThread) {
const M = 100;
const N = 100;
const matrixA = [];
for (let i = 1; i <= M; i++) {
// random numbers for each element of mat A
}
const matrixB = [];
for (let i = 1; i <= M; i++) {
// random numbers for each element of mat B
}
let matCCount = 0;
const totalCount = (M * N);
const matrixC = [];
const time1 = new Date();
let threadCount = 0;
const calculateResult = (matrixC) => {
const time2 = new Date();
console.log(`\nTime taken: ${(time2 - time1) / 1000}s`);
}
const mainService = function(getResult) {
for (let i = 0; i < M; i++) {
for (let j = 0; j < N; j++) {
let success = false;
do {
if (threadCount < 11) {
const worker = new Worker(__filename, { workerData: { i, j, matrixA, matrixB } });
threadCount ++;
worker.on('message', (message) => {
getResult(message);
success = true;
threadCount --;
});
worker.on('online', () => { console.log('online'); })
worker.on('error', (err) => {
console.log(err);
});
worker.on('exit', (code) => { console.log(code); })
}
} while (!success);
}
}
}
mainService((res) => {
const { i, j, result } = res;
if (matrixC[i] === undefined) {
matrixC[i] = [];
}
matrixC[i][j] = result;
matCCount += 1;
if (matCCount === totalCount) {
calculateResult(matrixC);
}
});
} else {
const { i, j, matrixA, matrixB } = workerData;
const x = multiplyOperation(i, j, matrixA, matrixB);
parentPort.postMessage({ i, j, result: x, threadId });
}
neither 'online' event is fired nor this console.log runs
} else {
console.log(threadId);
const { i, j, matrixA, matrixB } = workerData;
const x = multiplyOperation(i, j, matrixA, matrixB);
parentPort.postMessage({ i, j, result: x, threadId });
}
Related
I have a program that accepts POST requests with a body that contains numbers. My program checks is the numbers in body are prime numbers or not. Everything is well the first time, but every time after that the program remembers the past POST requests a checks them as well.
how can I reset the request queue so my program will only check the newest POST request?
here is the code:
import { createServer } from "http";
import { parse } from "querystring";
import { url } from "inspector";
import { port } from "./config.js";
let body = "";
let checkNumber = true;
const PORT = process.env.PORT || port;
const server = createServer(async (req, res) => {
res.statusCode = 200;
res.setHeader("Content-Type", "text/html");
const FORM_URLENCODED = "application/x-www-form-urlencoded";
const POST_PATH = "api/numbers/prime/validate";
const GET_PATH = "api/numbers/prime";
if (req.headers["content-type"] === FORM_URLENCODED) {
//console.log(req.method);
if (req.method === "POST") {
req.on("data", (chunk) => {
body += chunk.toString();
});
}
if (req.url === `/${POST_PATH}`) {
let re = parse(body);
await checkValuesInObject(re);
console.log(checkNumber);
res.end(`${checkNumber}`);
}
res.end();
});
server.listen(PORT, () => {
console.log(`listening on port ${PORT}`);
});
async function checkIfFirstNumber(number) {
if (number == 1) {
return false;
} else {
for (let i = 2; i < number - 1; i++) {
if (number % i === 0) {
return false;
}
}
return true;
}
}
async function checkValuesInObject(obj) {
const amount = Object.keys(obj);
for (let i = 0; i < amount.length; i++) {
let valueAmount = obj[Object.keys(obj)[i]];
for (let j = 0; j < valueAmount.length; j++) {
checkIfFirstNumber(valueAmount[j]).then((answer) => {
console.log(`answer: ${answer}`);
if (!answer) {
checkNumber = false;
}
});
}
}
checkNumber = true;
}
async function printPrime(number) {
let numbers = "";
for (let i = 2; i <= number; i++) {
const check = await checkIfFirstNumber(i);
if (check) {
numbers += i + " ";
}
}
return numbers;
}
I was expected the timerify function to return a number,
but instead I got a function instance, with node v16.5.0:
function someFunction() {
let sum = 0;
for (let i = 0; i < 1000000; i++) {
sum += i;
}
return sum;
}
const perf = performance.timerify(someFunction);
const result = perf();
console.log(result);
result:
someFunction {}
const { performance, PerformanceObserver } = require("perf_hooks");
function someFunction() {
let sum = 0;
for (let i = 0; i < 1000000; i++) {
sum += i;
}
return sum;
}
const perf = performance.timerify(someFunction);
const obs = new PerformanceObserver((list) => {
console.log('duration :: ', list.getEntries()[0].duration);
performance.clearMarks();
obs.disconnect();
});
obs.observe({ entryTypes: ["function"] });
// A performance timeline entry will be created
const result = perf();
console.log('result :: ',result);
This code is from https://medium.com/#Trott/using-worker-threads-in-node-js-80494136dbb6;
I have modified it to write it in Typescript, but I have a compilation error on:
test_workers_numbers.ts:50:18 - error TS2304: Cannot find name
'workerData'. 50 generatePrimes(workerData.start,
workerData.range)
What is the problem?
'use strict';
import {Worker, isMainThread, parentPort} from 'worker_threads';
const min = 2;
let primes:number[] = [];
function generatePrimes(start: number, range: number) {
let isPrime = true;
let end = start + range;
for (let i = start; i < end; i++) {
for (let j = min; j < Math.sqrt(end); j++) {
if (i !== j && i%j === 0) {
isPrime = false;
break;
}
}
if (isPrime) {
primes.push(i);
}
isPrime = true;
}
}
if (isMainThread) {
const max = 1e7;
const threadCount = +process.argv[2] || 2;
const threads = new Set<Worker>();;
console.log(`Running with ${threadCount} threads...`);
const range = Math.ceil((max - min) / threadCount);
let start = min;
for (let i = 0; i < threadCount - 1; i++) {
const myStart = start;
threads.add(new Worker(__filename, { workerData: { start: myStart, range }}));
start += range;
}
threads.add(new Worker(__filename, { workerData: { start, range: range + ((max - min + 1) % threadCount)}}));
for (let worker of Array.from(threads)) {
worker.on('error', (err) => { throw err; });
worker.on('exit', () => {
threads.delete(worker);
console.log(`Thread exiting, ${threads.size} running...`);
if (threads.size === 0) {
console.log(primes.join('\n'));
}
})
worker.on('message', (msg) => {
primes = primes.concat(msg);
});
}
} else {
generatePrimes(workerData.start, workerData.range);
parentPort.postMessage(primes);
}
worker.workerData is an arbitrary JavaScript value that contains a clone of the data passed to this thread’s Worker constructor so it needs to be imported. More info HERE
I want to console.log(price) print the return value of the function wraped after the '=>', but I'm printing the body of the request.
"use strict";
const request = require('request-promise');
const PromedioPonderado = require('../PromedioPonderado.js');
var exports = module.exports = {};
exports.GetPrices = async function(){
var price = await request('https://www.okex.com/api/v1/depth.do?symbol=btc_usdt', { json: true }, (err, res, body) => {
if (err) { return console.log(err); }
var promedio = new PromedioPonderado();
var bids = body.bids;
for (var i = 0, len = bids.length; i < len; i++) {
var row = bids[i];
var bid = {Price: row[0], Amount: row[1]}
promedio.bid(bid);
}
var asks = body.asks;
for (var i = 0, len = asks.length; i < len; i++) {
var row = asks[i];
var ask = {Price: row[0], Amount: row[1]}
promedio.ask(ask);
}
var askReturn = promedio.askAverage(); //sync function
var bidReturn = promedio.bidAverage(); // sync function
console.log(askReturn)
return {Ask: askReturn, Bid: bidReturn}; //I want to return this value
});
console.log(price);
}
This is PromedioPonderado.js, just in case
"use strict";
class PromedioPonderado {
constructor() {
this._bid = [];
this._ask = [];
}
bid(bid) {
this._bid.push(bid);
}
ask(ask){
this._ask.push(ask);
}
bidAverage(){
var totalAmount = 0;
var i = 0;
var average = 0;
while(totalAmount < 10){
totalAmount = totalAmount + this._bid[i].Amount;
average = average + (this._bid[i].Price * this._bid[i].Amount);
i++;
}
average = average / (totalAmount);
return average.toFixed(2);
}
askAverage(){
var totalAmount = 0;
var i = 0;
var average = 0;
while(totalAmount < 10){
totalAmount = totalAmount + this._ask[i].Amount;
average = average + (this._ask[i].Price * this._ask[i].Amount);
i++;
}
average = average / (totalAmount);
return average.toFixed(2);
}
}
module.exports = PromedioPonderado;
var body = await request('https://www.okex.com/api/v1/depth.do?symbol=btc_usdt', { json: true }
and then you can use the response from the request.
exports.GetPrices = async function(){
var price = await new Promise((resolve, reject) => {
request('https://www.okex.com/api/v1/depth.do?symbol=btc_usdt', { json: true }, (err, res, body) => {
if (err) { reject(err); }
var promedio = new PromedioPonderado();
var bids = body.bids;
for (var i = 0, len = bids.length; i < len; i++) {
var row = bids[i];
var bid = {Price: row[0], Amount: row[1]}
promedio.bid(bid);
}
var asks = body.asks;
for (var i = 0, len = asks.length; i < len; i++) {
var row = asks[i];
var ask = {Price: row[0], Amount: row[1]}
promedio.ask(ask);
}
var askReturn = promedio.askAverage(); //sync function
var bidReturn = promedio.bidAverage(); // sync function
console.log(askReturn)
resolve({Ask: askReturn, Bid: bidReturn}); //I want to return this value
});
})
console.log(price);
}
I have an example of shuffle bags with node.js is like this:
var shuffle = {
bag:function () {
var data = [], cursor = -1;
return {
add: function (item, num) {
var i = num || 1;
while (i--) {
data.push(item);
}
cursor = data.length - 1;
},
next: function () {
var grab, temp;
if (cursor < 1) {
cursor = data.length - 1;
return data[0];
}
grab = Math.floor(Math.random() * (cursor + 1));
temp = data[grab];
data[grab] = data[cursor];
data[cursor] = temp;
cursor--;
return temp;
}
};
}
};
But, I want to make a shuffle bag with mongodb. Does someone know if mongodb has a native thing for converting an entire collection in a sufflebag of docs?