Running several scripts with forever - node.js

I have several scripts in a directory, each of the scripts called bot and it's number, from 1 to the number of the scripts.
What I would like to do is somehow run all of the scripts by 1 command line through the terminal (Using Ubuntu), I've used forever command to run the script without stopping and etc.
Could you make it through the terminal or using a node js script?
Is there any other commands like forever that would do it for me?

You could use it through the command line with the command forever.
You'll need to create a JSON file with the files you need.
Example:
[
{
// App1
"uid": "app1", // ID of the script.
"append": true,
"watch": true,
"script": "bot1.js", // Name of the script
"sourceDir": "" // Where the script is located. If it's in the
// same location as the json file, leave it ""
},
{
// App2 = > Same as app1, just different script name.
"uid": "app2",
"append": true,
"watch": true,
"script": "bot2.js",
"sourceDir": ""
}
]
Then you need just to run the JSON file through the forever command.
Example:
forever start apps.json
You can see more information about forever here.

My answer is the same as the answer by #Nikita Ivanov but with pm2. I personally like pm2, which also uses a config file just like forever, but it can be a js, json or yaml file.
// JS File
module.exports = {
apps : [{
name: "bot1",
script: "./bot1.js",
watch: true, // some optional param just for example
env: {
"NODE_ENV": "development",
}, // some optional param just for example
env_production : {
"NODE_ENV": "production"
} // some optional param just for example
},{
name: "bot2",
script: "./bot2.js",
instances: 4, // some optional param just for example
exec_mode: "cluster" // some optional param just for example
}]
}
Now if you do not know the number of scripts there are, it ok. Since it is JS, you can write a script to get the list of all the files in the directory and create an array similar to the one above and use that config for pm2.
module.exports = (function () {
// logic to get all file names and create the 'apps' array
return {
apps: apps
}
})()
Furthermore, you can also use the pm2 npm module and use pm2 as a module in a js script and do this.
See PM2 DOCS for more info.

Related

How to override ava test runner's env variables while testing?

Ava test runner in my project has its own env variables defined like this in package.json:
"ava": {
"require": [
"esm"
],
"files": [
"test/unit/**/**/ava-*"
],
"environmentVariables": {
"SERVER_DEFAULT_TIMEZONE": "Australia/Sydney",
"PAY_MAX": "false",
"NODE_ENV": "development"
},
"timeout": "20s"
},
Now when doing a unit test for a certain file it happens that I need to cover this line in the function that I'm testing:
const isPayMax = process.env.PAY_MAX === "true";
So I'm trying to make that condition true so I can cover in my test. However, no matter I tried setting it to "true" or any other value, it still keep the value defined in package.json.
I've also tried using rewire module but it doesn't seem to work as well.
Also tried setting manually the environment variable in my test file like this process.env.PAY_MAX = "true" but no luck as well.
Any thoughts on how to deal with this? Thanks.

Access app.js function in adonisjs edge template

Can somebody explain to me how you access a function in the .edge template from the app.js file?
In resources/js/app.js I have
function myFunc() {
console.log("works???")
}
In the edge template I have
Some click
And I get the error
VM6192 :19 Uncaught ReferenceError: myFunc is not defined
at HTMLAnchorElement.onclick (VM6192 :19)
Note that I have the
<!-- Renders scripts -->
#entryPointScripts('app')
And the function is in the http://localhost:8080/assets/app.js path
I did manage to do something like window.myFunc = myFunc, inside app.js, but I need to call some async functions and I want the already compiled functions by webpack.
It seems that you do either:
map your function to window, in the app.js file (window.myFunc = myFunc), or
add an eventListener to the button you want
document.getElementById('my-btn').addEventListener('click', myFunc);
In order to make es6 work, with features like async/await, you need to add babel;
install the babel polyfill: https://babeljs.io/docs/en/babel-polyfill#installation
install core-js: https://github.com/zloirock/core-js#installation
create a .babelrc file with this configuration
{
"presets": [
[
"#babel/env",
{
"targets": {
"edge": "17",
"firefox": "60",
"chrome": "67",
"safari": "11.1"
},
"useBuiltIns": "usage",
"corejs": "3.16"
}
]
]
}
run node ace serve --watch again

Using pm2 with rabbitmq nodejs

I need to setup a nodejs cluster that uses pm2 to manage.
For communicating and passing message between the workers I am using rabbitmq.
I have gone through many articles but having some confusion basically regarding the flow.
These are the requirements:
When a order is created also create a booking for ordered services. Here I am thinking to pass the creation of booking to the worker process.
When a booking is created notify user and the devliery body also the admin.
This is what picture I have in my head for now.
I will start a node js cluster using pm2 as below.
// ecosystem.js
{
"apps" : [{
"name" : "API",
"script" : "server.js",// name of the startup file
"instances" : 4, // number of workers you want to run
"exec_mode" : "cluster", // to turn on cluster mode; defaults to 'fork' mode
"env": {
"PORT" : "9090" // the port on which the app should listen
}
}]
}
This is will start 4 workers.
Now How would I pass any task to these workers through rabbitmq?
Or should I another to workers for each task like.
NotificationWorker and BookingCreationWorker.
These two workers will wait for any task in their queue and process it?
i'll suggest you add a worker for BookingCreationWorker task and a consumer for NotificationWorker.js
{
apps: [
{
name: 'API',
script: 'server.js',
instances: 2,
watch: true,
exec_mode: "cluster",
max_memory_restart: '1G',
"env": {
"PORT" : "9090"
}
},
{
name: 'CreateBookWorker',
watch: true,
script: 'worker/BookingCreationWorker.js',
instances: 2
}
]
};

How to pass pm2 env variables into the node repl?

Imagine that I have some pm2 configuration file with some env variables into it:
"env" : {
"NODE_ENV": "development",
"MONGO_ENABLED" : true,
"MONGO_URI": "mongodb://localhost:27017/cindx-dev",
},
How can I run the node REPL, so all this environment variables will be enabled?
Thanks in advance!
I'm going to guess they use this code, if not some other code to load that.
https://github.com/Unitech/pm2/blob/91786108d71b3fc6c182750c09b494619e28b28a/lib/ProcessContainer.js#L16
// Load all env-vars from master.
var pm2_env = JSON.parse(process.env.pm2_env);
for(var k in pm2_env) {
process.env[k] = pm2_env[k];
}
So for you just run something like
var obj={
"NODE_ENV": "development",
"MONGO_ENABLED" : true,
"MONGO_URI": "mongodb://localhost:27017/cindx-dev",
};
Object.keys(obj).forEach(k=>process.env[k]=obj[k])

NODE_PATH is consumed by atom, it replaces my already in place NODE_PATH

I'm on a windows 10 environment writing a plugin for the Atom text editor to allow running tests through protractor cucumber from within atom it consumes the PlatformIO-Terminal plugin's provided service. When I activate that terminal plugin from within Atom I'd expect to be able to execute any old program from it that I could from my terminal that it's emulating through pty.
I'm having trouble executing any node program I've installed via npm outside of Atom's apm. Further digging via printing the environment variable NODE_PATH from within that terminal revealed that Atom has eaten my NODE_PATH value, not appended it's own but completely consumed and replaced it. Resetting it from within that pty window doesn't work, and neither does adding it to the "Shell Environment Variables" from within the PlatformIO configuration terminal. I've installed 3 plugins which allow pulling in environment variables from the OS, and none of them have succeeded.
Is there a way to solve this problem? I can access the executable modules directly, but they call other ones and depend on NODE_PATH.
If you aren't having success with terminal packages, you might try process-palette. It allows you to precisely define all of the details of the command, including environment variables. I've made an Atom command that sets NODE_ENV to an arbitrary string before executing a terminal command. Screenshots below:
Below is a process-palette.json file that defines the command I wrote. All you have to do to get started is install the package, make that file with the following code, and select Packages -> Process Palette -> Edit Configuration.
{
"patterns": {
"P1": {
"expression": "(path):(line)"
},
"P2": {
"expression": "(path)\\s+(line)",
"path": "(?:\\/[\\w\\.\\-]+)+"
}
},
"commands": [
{
"namespace": "process-palette",
"action": "env",
"command": "echo %NODE_PATH%",
"arguments": [],
"cwd": null,
"inputDialogs": [],
"env": {
"NODE_PATH": "wargarble"
},
"keystroke": null,
"stream": true,
"outputTarget": "panel",
"outputBufferSize": 80000,
"maxCompleted": 3,
"autoShowOutput": true,
"autoHideOutput": false,
"scrollLockEnabled": false,
"singular": false,
"promptToSave": true,
"saveOption": "none",
"patterns": [
"default"
],
"successOutput": "{stdout}",
"errorOutput": "{stdout}\n{stderr}",
"fatalOutput": "Failed to execute : {fullCommand}\n{stdout}\n{stderr}",
"startMessage": null,
"successMessage": "Executed : {fullCommand}",
"errorMessage": "Executed : {fullCommand}\nReturned with code {exitStatus}\n{stderr}",
"fatalMessage": "Failed to execute : {fullCommand}\n{stdout}\n{stderr}",
"menus": [
"env"
],
"startScript": null,
"successScript": null,
"errorScript": null,
"scriptOnStart": false,
"scriptOnSuccess": false,
"scriptOnError": false,
"notifyOnStart": false,
"notifyOnSuccess": true,
"notifyOnError": true,
"input": null
}
]
}

Resources