Skip to content

Commit

Permalink
fix: 🐛 fix timeout via worker_threads
Browse files Browse the repository at this point in the history
  • Loading branch information
maxbarsukov committed Jun 16, 2024
1 parent ff38fbb commit 1ed279a
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 70 deletions.
44 changes: 31 additions & 13 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import TelegramBot from "node-telegram-bot-api";
import { Worker } from "worker_threads";
import dotenv from "dotenv";

import { AppDataSource } from "@/data-source";
Expand Down Expand Up @@ -146,26 +147,43 @@ async function main() {
logger.info(context, ">> MATH EXPR");

const computeRequest = (): Promise<void> => {
return new Promise((resolve) => {
return new Promise((resolve, reject) => {
const mes = getMathExprs(message?.text?.toLowerCase());

if (mes !== null && mes?.length > 0) {
mes.forEach(me => {
const answer: string = computeMathExpr(me);

for (let i = 0, charsLength = answer.length; i < charsLength; i += MAX_MSG_LENGTH) {
bot.sendMessage(
message.chat.id,
answer.substring(i, i + MAX_MSG_LENGTH),
{ reply_to_message_id: message.message_id }
);
const worker = new Worker('./workers/calculator.ts');
worker.postMessage(mes);

worker.on('message', (result) => {
result.forEach((answer: string) => {
for (let i = 0, charsLength = answer.length; i < charsLength; i += MAX_MSG_LENGTH) {
bot.sendMessage(
message.chat.id,
answer.substring(i, i + MAX_MSG_LENGTH),
{ reply_to_message_id: message.message_id }
);
}
});

resolve(result);
worker.terminate();
});

worker.on('error', (error) => {
reject(error);
worker.terminate();
});

worker.on('exit', (code) => {
if (code !== 0) {
reject(new Error(`Worker stopped with exit code ${code}`));
}
});
} else {
reject(new Error("!!! No math expressions found"));
}

resolve();
});
}
};

(async () => {
try {
Expand Down
57 changes: 0 additions & 57 deletions src/utils/math.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ export function containsMathExpr(text: string | undefined): boolean {
return text.match(re) != null;
}

const abs = (n: bigint): bigint => (n < 0n) ? -n : n;

export function getMathExprs(text: string | undefined): ([bigint, string, bigint])[] | null {
if (text === undefined) {
return null;
Expand All @@ -27,58 +25,3 @@ export function getMathExprs(text: string | undefined): ([bigint, string, bigint
return [op1, groups[3], op2];
});
}

export function computeMathExpr(me: [bigint, string, bigint]): string {
const [ op1, operator, op2 ] = me;
const res = compute(op1, operator, op2);
if (res === 'Fuck u!') return `>> ${computeToExpr(op1, operator, op2)}`
const result = Number(res);

if ((result === 110 || result === 110) && operator == '+') return `${op1} ${operator} ${op2} = 100`;
if (op1 == 2n && operator == '+' && op2 == 2n) return '>> 2 + 2 = 32 / 8';
if (op1 == -2n && operator == '-' && op2 == 2n) return '>> -2 - 2 = -32 / 8';
if (op1 == -2n && operator == '+' && op2 == -2n) return '>> -2 + (-2) = -32 / 8';
if (abs(op1) == 2n && operator == '^' && abs(op2) == 2n) return `>> ${op1} ^ ${op2} = ${Math.abs(result) == result ? '' : '-'}32 / 8`;

if (abs(op1) == 32n && operator == '/' && abs(op2) == 8n) return `>> ${op1} / ${op2} = ${5 * (Math.abs(result) / result)}`;
if (abs(op1) == 32n && operator == '/' && abs(op2) == 5n) return `>> ${op1} / ${op2} = ${8 * (Math.abs(result) / result)}`;
if (abs(op1) == 8n && operator == '*' && abs(op2) == 5n) return `>> ${op1} * ${op2} = ${32 * (Math.abs(result) / result)}`;
if (abs(op1) == 5n && operator == '*' && abs(op2) == 8n) return `>> ${op1} * ${op2} = ${32 * (Math.abs(result) / result)}`;
if (abs(op1) == 32n && operator == '%' && abs(op2) == 8n) return `>> ${op1} % ${op2} = 0`;
if (abs(op1) == 32n && operator == '%' && abs(op2) == 5n) return `>> ${op1} % ${op2} = 0`;

if (abs(op1) == 2n && operator == '^' && abs(op2) == 5n) return '!!! Forbidden operation'
if (abs(op1) == 32n && operator == '/' && abs(op2) == 4n) return '!!! Forbidden operation'
if (abs(op1) == 32n && operator == '%' && abs(op2) == 4n) return '!!! Forbidden operation'
if (abs(op1) == 40n && operator == '/' && abs(op2) == 8n) return '!!! Forbidden operation'
if (abs(op1) == 8n && operator == '*' && abs(op2) == 4n) return '!!! Forbidden operation'
if (abs(op1) == 4n && operator == '*' && abs(op2) == 8n) return '!!! Forbidden operation'

if (op1 == 1000n && operator == '-' && op2 == 7n) return `>> У меня нет проблем, кроме моей башки ${computeToExpr(op1, operator, op2)}, я умер, прости.`
if (operator == '-' && op2 == 7n) return `>> ${(Math.random() < 0.5) ? 'Этот ёбаный дождь нагоняет тоски' : 'И им всем никогда меня не победить'} ${computeToExpr(op1, operator, op2)}, я уже погиб.`
if (operator == '+' && op2 == 7n) return `>> ${(Math.random() < 0.5) ? 'Этот славный денёк нагоняет радости' : 'И нам с друзьями очень весело жить'} ${computeToExpr(op1, operator, op2)}, я воскрес, спасибо, Господи!`
return `>> ${computeToExpr(op1, operator, op2)}`
}

function computeToExpr(op1: bigint, operator: string, op2: bigint): string {
return `${op1} ${operator} ${op2} = ${compute(op1, operator, op2)}`;
}

function compute(op1: bigint, operator: string, op2: bigint): bigint | number | 'Fuck u!' {
const ops = {
'+': (op1: bigint, op2: bigint): bigint => op1 + op2,
'^': (op1: bigint, op2: bigint): bigint => op1 ** op2,
'-': (op1: bigint, op2: bigint): bigint => op1 - op2,
'*': (op1: bigint, op2: bigint): bigint => op1 * op2,
'%': (op1: bigint, op2: bigint): bigint => op1 % op2,
'/': (op1: bigint, op2: bigint) => {
if (op2 == 0n) {
return 'Fuck u!';
} else {
return Number(op1) / Number(op2);
}
},
};

return ops[operator as keyof typeof ops](op1, op2);
}
63 changes: 63 additions & 0 deletions src/workers/calculator.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { parentPort } from "worker_threads";

const abs = (n) => (n < 0n) ? -n : n;

function computeMathExpr(me) {
const [ op1, operator, op2 ] = me;
const res = compute(op1, operator, op2);
if (res === 'Fuck u!') return `>> ${computeToExpr(op1, operator, op2)}`
const result = Number(res);

if ((result === 110 || result === 110) && operator == '+') return `${op1} ${operator} ${op2} = 100`;
if (op1 == 2n && operator == '+' && op2 == 2n) return '>> 2 + 2 = 32 / 8';
if (op1 == -2n && operator == '-' && op2 == 2n) return '>> -2 - 2 = -32 / 8';
if (op1 == -2n && operator == '+' && op2 == -2n) return '>> -2 + (-2) = -32 / 8';
if (abs(op1) == 2n && operator == '^' && abs(op2) == 2n) return `>> ${op1} ^ ${op2} = ${Math.abs(result) == result ? '' : '-'}32 / 8`;

if (abs(op1) == 32n && operator == '/' && abs(op2) == 8n) return `>> ${op1} / ${op2} = ${5 * (Math.abs(result) / result)}`;
if (abs(op1) == 32n && operator == '/' && abs(op2) == 5n) return `>> ${op1} / ${op2} = ${8 * (Math.abs(result) / result)}`;
if (abs(op1) == 8n && operator == '*' && abs(op2) == 5n) return `>> ${op1} * ${op2} = ${32 * (Math.abs(result) / result)}`;
if (abs(op1) == 5n && operator == '*' && abs(op2) == 8n) return `>> ${op1} * ${op2} = ${32 * (Math.abs(result) / result)}`;
if (abs(op1) == 32n && operator == '%' && abs(op2) == 8n) return `>> ${op1} % ${op2} = 0`;
if (abs(op1) == 32n && operator == '%' && abs(op2) == 5n) return `>> ${op1} % ${op2} = 0`;

if (abs(op1) == 2n && operator == '^' && abs(op2) == 5n) return '!!! Forbidden operation'
if (abs(op1) == 32n && operator == '/' && abs(op2) == 4n) return '!!! Forbidden operation'
if (abs(op1) == 32n && operator == '%' && abs(op2) == 4n) return '!!! Forbidden operation'
if (abs(op1) == 40n && operator == '/' && abs(op2) == 8n) return '!!! Forbidden operation'
if (abs(op1) == 8n && operator == '*' && abs(op2) == 4n) return '!!! Forbidden operation'
if (abs(op1) == 4n && operator == '*' && abs(op2) == 8n) return '!!! Forbidden operation'

if (op1 == 1000n && operator == '-' && op2 == 7n) return `>> У меня нет проблем, кроме моей башки ${computeToExpr(op1, operator, op2)}, я умер, прости.`
if (operator == '-' && op2 == 7n) return `>> ${(Math.random() < 0.5) ? 'Этот ёбаный дождь нагоняет тоски' : 'И им всем никогда меня не победить'} ${computeToExpr(op1, operator, op2)}, я уже погиб.`
if (operator == '+' && op2 == 7n) return `>> ${(Math.random() < 0.5) ? 'Этот славный денёк нагоняет радости' : 'И нам с друзьями очень весело жить'} ${computeToExpr(op1, operator, op2)}, я воскрес, спасибо, Господи!`
return `>> ${computeToExpr(op1, operator, op2)}`
}

function computeToExpr(op1, operator, op2) {
return `${op1} ${operator} ${op2} = ${compute(op1, operator, op2)}`;
}

function compute(op1, operator, op2) {
const ops = {
'+': (op1, op2) => op1 + op2,
'^': (op1, op2) => op1 ** op2,
'-': (op1, op2) => op1 - op2,
'*': (op1, op2) => op1 * op2,
'%': (op1, op2) => op1 % op2,
'/': (op1, op2) => {
if (op2 == 0n) {
return 'Fuck u!';
} else {
return Number(op1) / Number(op2);
}
},
};

return ops[operator](op1, op2);
}

parentPort.on("message", (mes) => {
const result = mes.map(me => computeMathExpr(me));
parentPort.postMessage(result);
});

0 comments on commit 1ed279a

Please sign in to comment.