my discord bot works well for a while but then "failed to bind to $PORT within 60 seconds of launch" - node.js

I've tried different approaches and looked at all the other replies but i dont know how to adress it
Error R10 (Boot timeout) -> Web process failed to bind to $PORT within 60 seconds of launch
2022-03-19T09:15:18.022903+00:00 heroku[web.1]: Stopping process with SIGKILL
2022-03-19T09:15:18.059850+00:00 app[web.1]: Error waiting for process to terminate: No child processes
2022-03-19T09:15:18.210022+00:00 heroku[web.1]: Process exited with status 22
2022-03-19T09:15:18.331083+00:00 heroku[web.1]: State changed from starting to crashed
the code:
require('dotenv').config();
const OpenAI = require('openai-api');
const openai = new OpenAI(process.env.OPENAI_API_KEY);
const { Client, Intents } = require('discord.js');
const client = new Client({ intents: [Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_MESSAGES] });
let prompt =`text here`;
client.on("message", function (message) {
if (message.author.bot) return;
prompt += `You: ${message.content}\n`;
(async () => {
const gptResponse = await openai.complete({
engine: 'davinci',
prompt: prompt,
maxTokens: 80,
temperature: 0.7,
topP: 1,
presencePenalty: 0,
frequencyPenalty: 0,
bestOf: 1,
n: 1,
stream: false,
stop: ['\n', '\n\n']
});
message.reply(`${gptResponse.data.choices[0].text.substring(5)}`);
prompt += `${gptResponse.data.choices[0].text}\n`;
})();
});
client.login(process.env.BOT_TOKEN);
my procfile is empty but it still works for 60 seconds
any ideas?
edit: THINGS I TRIED THAT DONT WORK
i tried changing procfile to contain
worker: node index.js
procfile to worker: java -jar build/libs/*.jar

Use the name Procfile instead of procfile, otherwise heroku doesn't learns that you need worker process and not the default web process.

Related

ExpressJS Node Process won't end "normally"

NodeJS v 16.15.1 Windows 10.
Since a few days, neither nodemon nor VSCode can end node processes which use app.listen() of express. When the code changes we see:
[nodemon] restarting due to changes...
But nothing happens after that. We have to kill the processes manually in task manager.
'use strict';
const express = require('express');
const app = express();
const PORT = 8040;
// The PROBLEMATIC line:
app.listen(PORT, () => {
console.log(`Started on http://localhost:${PORT} (PID: ${process.pid})`);
});
If I remove "The PROBLEMATIC line" then nodemon/vscode can restart the process.
There is NO error message, the app just does not exit. For example by entering rs:
Nothing happens, no matter how long I wait.
Using nodemon --signal SIGTERM makes no difference, the process never sees the SIGTERM.
Using the package why-is-node-running we see:
There are 5 handle(s) keeping the process running
# TCPSERVERWRAP
C:\services\overview\node_modules\express\lib\application.js:635 - return server.listen.apply(server, arguments);
C:\services\overview\src\tmp2.js:6 - app.listen(PORT, () => {
# TTYWRAP
C:\services\overview\src\tmp2.js:7 - console.log(`Started on http://localhost:${PORT} (PID: ${process.pid})`);
# HTTPINCOMINGMESSAGE
(unknown stack trace)
# HTTPINCOMINGMESSAGE
(unknown stack trace)
# TickObject
(unknown stack trace)
You want end the node/nodemon process? Why not using ctrl + c instead

Puppeteer on Heroku Error R10 (Boot timeout) Node (webscraping app)

I created a web scraping app, which checks for a certain problem on an ecommerce website.
What it does:
Loops through an array of pages
checks for a condition on every page
if condition is met - pushes page to temparray
sends an email with temparray as body
I wrapped that function in a cronjob function.
On my local machine it runs fine.
Deployed like this:
headless: true
'--no-sandbox',
'--disable-setuid-sandbox'
Added the pptr buildpack link to settings in heroku
slugsize is 259.6 MiB of 500 MiB
It didnt work.
set boot timeout to 120s (instead of 60s)
It worked. But only ran once.
Since it want to run that function several times per day, I need to fix the issue.
I have another app running which uses the same cronjob and notification function and it works on heroku.
Here's my code, if anyone is interested.
const puppeteer = require('puppeteer');
const nodemailer = require("nodemailer");
const CronJob = require('cron').CronJob;
let articleInfo ='';
const mailArr = [];
let body = '';
const testArr = [
'https://bxxxx..', https://b.xxx..', https://b.xxxx..',
];
async function sendNotification() {
let transporter = nodemailer.createTransport({
host: 'mail.brxxxxx.dxx',
port: 587,
secure: false,
auth: {
user: 'hey#b.xxxx',
pass: process.env.heyBfPW2
}
});
let textToSend = 'This is the heading';
let htmlText = body;
let info = await transporter.sendMail({
from: '"BB Checker" <hey#baxxxxx>',
to: "sxx..xx...xx#gmail.com",
subject: 'Hi there',
text: textToSend,
html: htmlText
});
console.log("Message sent: %s", info.messageId);
}
async function boxLookUp (item) {
const browser = await puppeteer.launch({
headless: true,
args: [
'--no-sandbox',
'--disable-setuid-sandbox',
],
});
const page = await browser.newPage();
await page.goto(item);
const content = await page.$eval('.set-article-info', div => div.textContent);
const title = await page.$eval('.product--title', div => div.textContent);
const orderNumber = await page.$eval('.entry--content', div => div.textContent);
// Check if deliveryTime is already updated
try {
await page.waitForSelector('.delivery--text-more-is-coming');
// if not
} catch (e) {
if (e instanceof puppeteer.errors.TimeoutError) {
// if not updated check if all parts of set are available
if (content != '3 von 3 Artikeln ausgewählt' && content != '4 von 4 Artikeln ausgewählt' && content != '5 von 5 Artikeln ausgewählt'){
articleInfo = `${title} ${orderNumber} ${item}`;
mailArr.push(articleInfo)
}
}
}
await browser.close();
};
const checkBoxes = async (arr) => {
for (const i of arr) {
await boxLookUp(i);
}
console.log(mailArr)
body = mailArr.toString();
sendNotification();
}
async function startCron() {
let job = new CronJob('0 */10 8-23 * * *', function() { // run every_10_minutes_between_8_and_11
checkBoxes(testArr);
}, null, true, null, null, true);
job.start();
}
startCron();
Had the same issue for 3 days now. Here something that might help: https://stackoverflow.com/a/55861535/13735374
Has to be done alongside the Procfile thing.
Assuming the rest of the code works (nodemailer, etc), I'll simplify the problem to focus purely on running a scheduled Node Puppeteer task in Heroku. You can re-add your mailing logic once you have a simple example running.
Heroku runs scheduled tasks using simple job scheduling or a custom clock process.
Simple job scheduling doesn't give you much control, but is easier to set up and potentially less expensive in terms of billable hours if you're running it infrequently. The custom clock, on the other hand, will be a continuously-running process and therefore chew up hours.
A custom clock process can do your cron task exactly, so that's probably the natural fit for this case.
For certain scenarios, you can sometimes workaround on the simple scheduler to do more complicated schedules by having it exit early or by deploying multiple apps.
For example, if you want a twice-daily schedule, you could have two apps that run the same task scheduled at different hours of the day. Or, if you wanted to run a task twice weekly, schedule it to run daily using the simple scheduler, then have it check its own time and exit immediately if the current day isn't one of the two desired days.
Regardless of whether you use a custom clock or simple scheduled task, note that long-running tasks really should be handled by a background task, so the examples below aren't production-ready. That's left as an exercise for the reader and isn't Puppeteer-specific.
Custom clock process
package.json:
{
"name": "test-puppeteer",
"version": "1.0.0",
"description": "",
"scripts": {
"start": "echo 'running'"
},
"author": "",
"license": "ISC",
"dependencies": {
"cron": "^1.8.2",
"puppeteer": "^9.1.1"
}
}
Procfile
clock: node clock.js
clock.js:
const {CronJob} = require("cron");
const puppeteer = require("puppeteer");
// FIXME move to a worker task; see https://devcenter.heroku.com/articles/node-redis-workers
const scrape = async () => {
const browser = await puppeteer.launch({
args: ["--no-sandbox", "--disable-setuid-sandbox"]
});
const [page] = await browser.pages();
await page.setContent(`<p>clock running at ${Date()}</p>`);
console.log(await page.content());
await browser.close();
};
new CronJob({
cronTime: "30 * * * * *", // run every 30 seconds for demonstration purposes
onTick: scrape,
start: true,
});
Set up
Install Heroku CLI and create a new app with Node and Puppeteer buildpacks (see this answer):
heroku create
heroku buildpacks:add --index 1 https://github.com/jontewks/puppeteer-heroku-buildpack -a cryptic-dawn-48835
heroku buildpacks:add --index 1 heroku/nodejs -a cryptic-dawn-48835
(replace cryptic-dawn-48835 with your app name)
Deploy:
git init
git add .
git commit -m "initial commit"
heroku git:remote -a cryptic-dawn-48835
git push heroku master
Add a clock process:
heroku ps:scale clock=1
Verify that it's running with heroku logs --tail. heroku ps:scale clock=0 turns off the clock.
Simple scheduler
package.json:
Same as above, but no need for cron. No need for a Procfile either.
task.js:
const puppeteer = require("puppeteer");
(async () => {
const browser = await puppeteer.launch({
args: ["--no-sandbox", "--disable-setuid-sandbox"]
});
const [page] = await browser.pages();
await page.setContent(`<p>scheduled job running at ${Date()}</p>`);
console.log(await page.content());
await browser.close();
})();
Set up
Install Heroku CLI and create a new app with Node and Puppeteer buildpacks (see this answer):
heroku create
heroku buildpacks:add --index 1 https://github.com/jontewks/puppeteer-heroku-buildpack -a cryptic-dawn-48835
heroku buildpacks:add --index 1 heroku/nodejs -a cryptic-dawn-48835
(replace cryptic-dawn-48835 with your app name)
Deploy:
git init
git add .
git commit -m "initial commit"
heroku git:remote -a cryptic-dawn-48835
git push heroku master
Add a scheduler:
heroku addons:add scheduler:standard -a cryptic-dawn-48835
Configure the scheduler by running:
heroku addons:open scheduler -a cryptic-dawn-48835
This opens a browser and you can add a command node task.js to run every 10 minutes.
Verify that it worked after 10 minutes with heroku logs --tail. The online scheduler will show the time of next/previous execution.
See this answer for creating an Express-based web app on Heroku with Puppeteer.

Despite app.listen, express app does not bind to port

Exactly what it sounds like.
I use ExpressJS for my Node app, which is hosted on Heroku.
Despite using app.listen, it consistently is getting / causing heroku R10 errors, which are caused by a web app not binding to process.env.PORT in time.
The relevant code:
const app = express();
var isRoot = (process.getuid && (process.getuid() === 0));
var port;
if (isRoot) {
port = 80;
} else {
port = process.env.PORT | 8000;
}
const server = app.listen(port, onStartup);
function onStartup() {
console.log("Started webserver on port "+port);
}
Now the odd thing is, I'm getting the "Started webserver on port [foo]" message, it's just not binding to the port.
Logs:
2020-03-30T19:50:39.434302+00:00 app[web.1]: > foo-bar#1.0.0 start /app
2020-03-30T19:50:39.434303+00:00 app[web.1]: > node scrape2.js
2020-03-30T19:50:39.434303+00:00 app[web.1]:
2020-03-30T19:50:39.829882+00:00 app[web.1]: Verbose mode OFF
2020-03-30T19:50:39.830782+00:00 app[web.1]: Started webserver on port 8052
2020-03-30T19:51:37.415192+00:00 heroku[web.1]: State changed from starting to crashed
2020-03-30T19:51:37.293060+00:00 heroku[web.1]: Error R10 (Boot timeout) -> Web process failed to bind to $PORT within 60 seconds of launch
2020-03-30T19:51:37.293142+00:00 heroku[web.1]: Stopping process with SIGKILL
2020-03-30T19:51:37.391762+00:00 heroku[web.1]: Process exited with status 137
Help!
I did a stupid and accidentally used the bitwise OR operator, which caused it to bind to a different port than process.env.PORT. Changed it from | to || and it works fine now.

how to kill command line process start with child_process nodejs

how can i stop it, it keep running after i stop nodejs. I try process.kill() but not working
const process = require('child_process')
const child = process.exec('ping 8.8.8.8 -t')
setTimeout(()=>child.kill(2),10000)
after a few hour reading nodejs docs, i found this for who have same my problem
const process = require('child_process')
const child = process.execFile('ping 8.8.8.8',['-t'],{cwd:'your working direct'})
setTimeout(()=>child.kill(2),10000)//now kill() working
I modified your code as below to flush out the error:
const process = require('child_process')
const child = process.spawn('ping 8.8.8.8 -t') // instead of process.exec
setTimeout(() => {
console.log(child.kill(2)) // --> false == failed
}, 10000);
child.on('error', (code, signal) => {
console.log(`${code}`) // --> Error: spawn ping 8.8.8.8 -t ENOENT
});
The ping command requires an argument after the -t ( as per terminal: ping: option requires an argument -- t

Error when running firebase node app on Heroku

The code (server.js) is as following following the Firebase documentation example
var firebase = require("firebase");
firebase.initializeApp({
databaseURL: "https://mydatabaseName.firebaseio.com",
});
var db = firebase.database();
var ref = db.ref("/Users");
ref.on("value", function(snapshot) {
console.log(snapshot.val());
});
but I'm running into the error
Error waiting for process to terminate: No child processes
State changed from starting to crashed
Error R10 (Boot timeout) -> Web process failed to bind to $PORT within 60 seconds of launch
Stopping process with SIGKILL
Process exited with status 22
After googling this issue, I tried adding to the Procfile
worker: node server.js
heroku ps:scale worker=1 web=0
None of these seemed to work. Any suggestions?

Resources