downloaded Server folder and replaced it

This commit is contained in:
MuhammadKhalilzadeh committed 2024-05-17 09:46:17 +03:30
1 parent 3a5c889a8b
commit b2c8e50043
7 files changed
+440 -27

No files matched your search

+8 -8
View File
@@ -1,7 +1,5 @@
const express = require("express");
const UserModel = require("../models/user");
const { registerValidation } = require("../validation/joi");
const logger = require('../utils/logger')
const logger = require("../utils/logger");
/**
* @function
@@ -23,26 +21,28 @@ const registerController = async (req, res) => {
try {
const isUser = await req.db.getUserByEmail(req, res);
if (isUser) {
logger.warning("User already exists!", { "service": "auth", "userId": isUser._id });
logger.warning("User already exists!", {
service: "auth",
userId: isUser._id,
});
return res
.status(400)
.json({ success: false, msg: "User already exists!" });
}
} catch (error) {
logger.error(error.message, { "service": "auth" });
logger.error(error.message, { service: "auth" });
return res.status(500).json({ success: false, msg: error.message });
}
try {
// Create a new user
const newUser = await req.db.insertUser(req, res);
// TODO: Send an email to user
// Will add this later
logger.info("New user created!", { "service": "auth", "userId": newUser._id });
logger.info("New user created!", { service: "auth", userId: newUser._id });
return res.json({ success: true, msg: "User created}", data: newUser });
} catch (error) {
logger.error(error.message, { "service": "auth" });
logger.error(error.message, { service: "auth" });
return res.status(500).json({ success: false, msg: error.message });
}
};
+8 -5
View File
@@ -2,7 +2,7 @@ const {
getMonitorsByIdValidation,
getMonitorsByUserIdValidation,
} = require("../validation/joi");
const logger = require('../utils/logger')
const logger = require("../utils/logger");
// Gets all monitors
const getAllMonitors = async (req, res) => {
@@ -10,7 +10,7 @@ const getAllMonitors = async (req, res) => {
const monitors = await req.db.getAllMonitors();
return res.json({ success: true, msg: "Monitors found", data: monitors });
} catch (error) {
logger.error(error.message, { "service": "monitor" });
logger.error(error.message, { service: "monitor" });
return res.status(500).json({ success: false, msg: error.message });
}
};
@@ -29,7 +29,7 @@ const getMonitorById = async (req, res) => {
const monitor = await req.db.getMonitorById(monitorId);
return res.json({ success: true, msg: "Monitor found", data: monitor });
} catch (error) {
logger.error(error.message, { "service": "monitor" });
logger.error(error.message, { service: "monitor" });
return res.status(500).json({ success: false, msg: error.message });
}
};
@@ -46,14 +46,17 @@ const getMonitorsByUserId = async (req, res) => {
try {
const userId = req.params.userId;
const monitors = await req.db.getMonitorsByUserId(userId);
logger.info(`Monitors for user ${userId} found`, { "service": "monitor", "userId":userId });
logger.info(`Monitors for user ${userId} found`, {
service: "monitor",
userId: userId,
});
return res.json({
success: true,
msg: `Monitors for user ${userId} found`,
data: monitors,
});
} catch (error) {
logger.error(error.message, { "service": "monitor" });
logger.error(error.message, { service: "monitor" });
return res.status(500).json({ success: false, msg: error.message });
}
};
+2 -2
View File
@@ -26,7 +26,7 @@ const UserModel = require("../models/user");
const FAKE_MONITOR_DATA = [];
const USERS = [];
for (let i = 0; i < 10; i++) {
for (let i = 0; i < 1; i++) {
FAKE_MONITOR_DATA.push(
new Monitor({
userId: i % 2 === 0 ? 1 : 2,
@@ -34,7 +34,7 @@ for (let i = 0; i < 10; i++) {
description: `Description for Monitor ${i}`,
url: `https://monitor${i}.com`,
isActive: true,
interval: 60000,
interval: Math.floor(Math.random() * 10) + 1,
updated_at: new Date(),
created_at: new Date(),
})
+31 -12
View File
@@ -7,20 +7,29 @@ const { connectDbAndRunServer } = require("./configs/db");
require("dotenv").config();
const logger = require("./utils/logger");
// const { sendEmail } = require('./utils/sendEmail')
const pingSerivce = require("./service/pingService");
// **************************
// Here is where we can swap out DBs easily. Spin up a mongoDB instance and try it out.
// Simply comment out the FakeDB and uncomment the MongoDB or vice versa.
// We can easily swap between any type of data source as long as the methods are implemented
//
// FakeDB
// const db = require("./db/FakeDb");
//
// MongoDB
const db = require("./db/MongoDB");
//
// **************************
/**
* DB Notes
* Here is where we can swap out DBs easily. Spin up a mongoDB instance and try it out.
* Simply comment out the FakeDB and uncomment the MongoDB or vice versa.
* We can easily swap between any type of data source as long as the methods are implemented
*
* FakeDB
* const db = require("./db/FakeDb");
*
* MongoDB
* const db = require("./db/MongoDB");
*/
const DB_TYPE = {
MongoDB: () => require("./db/MongoDB"),
FakedDB: () => require("./db/FakeDb"),
};
const db = DB_TYPE[process.env.DB_TYPE]
? DB_TYPE[process.env.DB_TYPE]()
: require("./db/FakeDb");
/**
* NOTES
* Email Service will be added
@@ -70,3 +79,13 @@ app.use("/api/v1/healthy", (req, res) => {
});
connectDbAndRunServer(app, db);
pingSerivce.startPingService(db);
// Cleanup
const cleanup = async () => {
await pingSerivce.cleanup();
process.exit(0);
};
process.on("SIGINT", cleanup);
process.on("SIGTERM", cleanup);
+267
View File
@@ -10,6 +10,7 @@
"license": "ISC",
"dependencies": {
"bcrypt": "^5.1.1",
"bullmq": "5.7.8",
"cors": "^2.8.5",
"dotenv": "^16.4.5",
"express": "^4.19.2",
@@ -54,6 +55,11 @@
"@hapi/hoek": "^9.0.0"
}
},
"node_modules/@ioredis/commands": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/@ioredis/commands/-/commands-1.2.0.tgz",
"integrity": "sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg=="
},
"node_modules/@mapbox/node-pre-gyp": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz",
@@ -95,6 +101,78 @@
"sparse-bitfield": "^3.0.3"
}
},
"node_modules/@msgpackr-extract/msgpackr-extract-darwin-arm64": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-arm64/-/msgpackr-extract-darwin-arm64-3.0.2.tgz",
"integrity": "sha512-9bfjwDxIDWmmOKusUcqdS4Rw+SETlp9Dy39Xui9BEGEk19dDwH0jhipwFzEff/pFg95NKymc6TOTbRKcWeRqyQ==",
"cpu": [
"arm64"
],
"optional": true,
"os": [
"darwin"
]
},
"node_modules/@msgpackr-extract/msgpackr-extract-darwin-x64": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-x64/-/msgpackr-extract-darwin-x64-3.0.2.tgz",
"integrity": "sha512-lwriRAHm1Yg4iDf23Oxm9n/t5Zpw1lVnxYU3HnJPTi2lJRkKTrps1KVgvL6m7WvmhYVt/FIsssWay+k45QHeuw==",
"cpu": [
"x64"
],
"optional": true,
"os": [
"darwin"
]
},
"node_modules/@msgpackr-extract/msgpackr-extract-linux-arm": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm/-/msgpackr-extract-linux-arm-3.0.2.tgz",
"integrity": "sha512-MOI9Dlfrpi2Cuc7i5dXdxPbFIgbDBGgKR5F2yWEa6FVEtSWncfVNKW5AKjImAQ6CZlBK9tympdsZJ2xThBiWWA==",
"cpu": [
"arm"
],
"optional": true,
"os": [
"linux"
]
},
"node_modules/@msgpackr-extract/msgpackr-extract-linux-arm64": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm64/-/msgpackr-extract-linux-arm64-3.0.2.tgz",
"integrity": "sha512-FU20Bo66/f7He9Fp9sP2zaJ1Q8L9uLPZQDub/WlUip78JlPeMbVL8546HbZfcW9LNciEXc8d+tThSJjSC+tmsg==",
"cpu": [
"arm64"
],
"optional": true,
"os": [
"linux"
]
},
"node_modules/@msgpackr-extract/msgpackr-extract-linux-x64": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-x64/-/msgpackr-extract-linux-x64-3.0.2.tgz",
"integrity": "sha512-gsWNDCklNy7Ajk0vBBf9jEx04RUxuDQfBse918Ww+Qb9HCPoGzS+XJTLe96iN3BVK7grnLiYghP/M4L8VsaHeA==",
"cpu": [
"x64"
],
"optional": true,
"os": [
"linux"
]
},
"node_modules/@msgpackr-extract/msgpackr-extract-win32-x64": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-win32-x64/-/msgpackr-extract-win32-x64-3.0.2.tgz",
"integrity": "sha512-O+6Gs8UeDbyFpbSh2CPEz/UOrrdWPTBYNblZK5CxxLisYt4kGX3Sc+czffFonyjiGSq3jWLwJS/CCJc7tBr4sQ==",
"cpu": [
"x64"
],
"optional": true,
"os": [
"win32"
]
},
"node_modules/@sideway/address": {
"version": "4.1.5",
"resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz",
@@ -310,6 +388,20 @@
"node": ">=16.20.1"
}
},
"node_modules/bullmq": {
"version": "5.7.8",
"resolved": "https://registry.npmjs.org/bullmq/-/bullmq-5.7.8.tgz",
"integrity": "sha512-F/Haeu6AVHkFrfeaU/kLOjhfrH6x3CaKAZlQQ+76fa8l3kfI9oaUHeFMW+1mYVz0NtYPF7PNTWFq4ylAHYcCgA==",
"dependencies": {
"cron-parser": "^4.6.0",
"ioredis": "^5.4.1",
"msgpackr": "^1.10.1",
"node-abort-controller": "^3.1.1",
"semver": "^7.5.4",
"tslib": "^2.0.0",
"uuid": "^9.0.0"
}
},
"node_modules/bytes": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
@@ -368,6 +460,14 @@
"node": ">=10"
}
},
"node_modules/cluster-key-slot": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz",
"integrity": "sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/color": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz",
@@ -470,6 +570,17 @@
"node": ">= 0.10"
}
},
"node_modules/cron-parser": {
"version": "4.9.0",
"resolved": "https://registry.npmjs.org/cron-parser/-/cron-parser-4.9.0.tgz",
"integrity": "sha512-p0SaNjrHOnQeR8/VnfGbmg9te2kfyYSQ7Sc/j/6DtPL3JQvKxmjO9TSjNFpujqV3vEYYBvNNvXSxzyksBWAx1Q==",
"dependencies": {
"luxon": "^3.2.1"
},
"engines": {
"node": ">=12.0.0"
}
},
"node_modules/debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
@@ -499,6 +610,14 @@
"resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
"integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ=="
},
"node_modules/denque": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz",
"integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==",
"engines": {
"node": ">=0.10"
}
},
"node_modules/depd": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
@@ -978,6 +1097,50 @@
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
},
"node_modules/ioredis": {
"version": "5.4.1",
"resolved": "https://registry.npmjs.org/ioredis/-/ioredis-5.4.1.tgz",
"integrity": "sha512-2YZsvl7jopIa1gaePkeMtd9rAcSjOOjPtpcLlOeusyO+XH2SK5ZcT+UCrElPP+WVIInh2TzeI4XW9ENaSLVVHA==",
"dependencies": {
"@ioredis/commands": "^1.1.1",
"cluster-key-slot": "^1.1.0",
"debug": "^4.3.4",
"denque": "^2.1.0",
"lodash.defaults": "^4.2.0",
"lodash.isarguments": "^3.1.0",
"redis-errors": "^1.2.0",
"redis-parser": "^3.0.0",
"standard-as-callback": "^2.1.0"
},
"engines": {
"node": ">=12.22.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/ioredis"
}
},
"node_modules/ioredis/node_modules/debug": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
"integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
"dependencies": {
"ms": "2.1.2"
},
"engines": {
"node": ">=6.0"
},
"peerDependenciesMeta": {
"supports-color": {
"optional": true
}
}
},
"node_modules/ioredis/node_modules/ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
},
"node_modules/ipaddr.js": {
"version": "1.9.1",
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
@@ -1086,6 +1249,16 @@
"resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz",
"integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A=="
},
"node_modules/lodash.defaults": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz",
"integrity": "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ=="
},
"node_modules/lodash.isarguments": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz",
"integrity": "sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg=="
},
"node_modules/logform": {
"version": "2.6.0",
"resolved": "https://registry.npmjs.org/logform/-/logform-2.6.0.tgz",
@@ -1118,6 +1291,14 @@
"node": ">=10"
}
},
"node_modules/luxon": {
"version": "3.4.4",
"resolved": "https://registry.npmjs.org/luxon/-/luxon-3.4.4.tgz",
"integrity": "sha512-zobTr7akeGHnv7eBOXcRgMeCP6+uyYsczwmeRCauvpvaAltgNyTbLH/+VaEAPUeWBT+1GuNmz4wC/6jtQzbbVA==",
"engines": {
"node": ">=12"
}
},
"node_modules/mailersend": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/mailersend/-/mailersend-2.2.0.tgz",
@@ -1384,6 +1565,35 @@
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
},
"node_modules/msgpackr": {
"version": "1.10.2",
"resolved": "https://registry.npmjs.org/msgpackr/-/msgpackr-1.10.2.tgz",
"integrity": "sha512-L60rsPynBvNE+8BWipKKZ9jHcSGbtyJYIwjRq0VrIvQ08cRjntGXJYW/tmciZ2IHWIY8WEW32Qa2xbh5+SKBZA==",
"optionalDependencies": {
"msgpackr-extract": "^3.0.2"
}
},
"node_modules/msgpackr-extract": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/msgpackr-extract/-/msgpackr-extract-3.0.2.tgz",
"integrity": "sha512-SdzXp4kD/Qf8agZ9+iTu6eql0m3kWm1A2y1hkpTeVNENutaB0BwHlSvAIaMxwntmRUAUjon2V4L8Z/njd0Ct8A==",
"hasInstallScript": true,
"optional": true,
"dependencies": {
"node-gyp-build-optional-packages": "5.0.7"
},
"bin": {
"download-msgpackr-prebuilds": "bin/download-prebuilds.js"
},
"optionalDependencies": {
"@msgpackr-extract/msgpackr-extract-darwin-arm64": "3.0.2",
"@msgpackr-extract/msgpackr-extract-darwin-x64": "3.0.2",
"@msgpackr-extract/msgpackr-extract-linux-arm": "3.0.2",
"@msgpackr-extract/msgpackr-extract-linux-arm64": "3.0.2",
"@msgpackr-extract/msgpackr-extract-linux-x64": "3.0.2",
"@msgpackr-extract/msgpackr-extract-win32-x64": "3.0.2"
}
},
"node_modules/negotiator": {
"version": "0.6.3",
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
@@ -1392,6 +1602,11 @@
"node": ">= 0.6"
}
},
"node_modules/node-abort-controller": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-3.1.1.tgz",
"integrity": "sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ=="
},
"node_modules/node-addon-api": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz",
@@ -1435,6 +1650,17 @@
"webidl-conversions": "^3.0.0"
}
},
"node_modules/node-gyp-build-optional-packages": {
"version": "5.0.7",
"resolved": "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.0.7.tgz",
"integrity": "sha512-YlCCc6Wffkx0kHkmam79GKvDQ6x+QZkMjFGrIMxgFNILFvGSbCp2fCBC55pGTT9gVaz8Na5CLmxt/urtzRv36w==",
"optional": true,
"bin": {
"node-gyp-build-optional-packages": "bin.js",
"node-gyp-build-optional-packages-optional": "optional.js",
"node-gyp-build-optional-packages-test": "build-test.js"
}
},
"node_modules/nodemon": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.0.tgz",
@@ -1684,6 +1910,25 @@
"node": ">=8.10.0"
}
},
"node_modules/redis-errors": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/redis-errors/-/redis-errors-1.2.0.tgz",
"integrity": "sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w==",
"engines": {
"node": ">=4"
}
},
"node_modules/redis-parser": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-3.0.0.tgz",
"integrity": "sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A==",
"dependencies": {
"redis-errors": "^1.0.0"
},
"engines": {
"node": ">=4"
}
},
"node_modules/rimraf": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
@@ -1875,6 +2120,11 @@
"node": "*"
}
},
"node_modules/standard-as-callback": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/standard-as-callback/-/standard-as-callback-2.1.0.tgz",
"integrity": "sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A=="
},
"node_modules/statuses": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
@@ -1999,6 +2249,11 @@
"node": ">= 14.0.0"
}
},
"node_modules/tslib": {
"version": "2.6.2",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
},
"node_modules/type-is": {
"version": "1.6.18",
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
@@ -2043,6 +2298,18 @@
"node": ">= 0.4.0"
}
},
"node_modules/uuid": {
"version": "9.0.1",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz",
"integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==",
"funding": [
"https://github.com/sponsors/broofa",
"https://github.com/sponsors/ctavan"
],
"bin": {
"uuid": "dist/bin/uuid"
}
},
"node_modules/vary": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
+1
View File
@@ -12,6 +12,7 @@
"license": "ISC",
"dependencies": {
"bcrypt": "^5.1.1",
"bullmq": "5.7.8",
"cors": "^2.8.5",
"dotenv": "^16.4.5",
"express": "^4.19.2",
+123
View File
@@ -0,0 +1,123 @@
const { Queue, Worker } = require("bullmq");
const logger = require("../utils/logger");
require("dotenv").config();
/**
* NOTES
* This code will be resource heavy as we will be creating
* many workers and jobs. Operations should be robust and have good
* error handling and retry functionality.
* There will be a lot of I/O operations as well, so we should be
* aware of asynchronous operations and handle them properly.
*/
const connection = {
host: process.env.BULL_MQ_HOST || "127.0.0.1",
port: process.env.BULL_MQ_PORT || 6379,
};
const JOBS_PER_WORKER = 5;
const MAX_CREATE_WORKER_RETRIES = 3;
const SERVICE_NAME = "pingService";
const QUEUE_NAME = "monitors";
let queue;
let workers = [];
const enqueueJob = async (queue, monitor) => {
try {
await queue.add(
QUEUE_NAME,
{ monitor },
{ delay: monitor.interval * 1000 }
);
logger.info("Job enqueued", { service: SERVICE_NAME });
} catch (error) {
logger.error(error.message, { service: SERVICE_NAME });
}
};
const pingMonitor = (monitor) => {
// TODO Implement pinging the monitor
console.log(`{url: ${monitor.url},`, `interval: ${monitor.interval}}`);
};
const createWorker = (queue, retries = 0) => {
try {
const worker = new Worker(
QUEUE_NAME,
async (job) => {
//Ping the monitor and enqueue the job again to constantly monitor
pingMonitor(job.data.monitor);
enqueueJob(queue, job.data.monitor);
},
{
connection,
}
);
logger.info("Worker created", { service: SERVICE_NAME });
return worker;
} catch (error) {
logger.error(error.message, { service: SERVICE_NAME });
// If creating a worker fails, recursively retry MAX_CREATE_WORKER_RETRIES times
if (retries < MAX_CREATE_WORKER_RETRIES) {
logger.info(
`Retrying to create worker (${
retries + 1
}/${MAX_CREATE_WORKER_RETRIES})`,
{ service: SERVICE_NAME }
);
return createWorker(queue, retries + 1);
}
return null;
}
};
const startPingService = async (db) => {
queue = new Queue(QUEUE_NAME, {
connection,
});
const monitors = await db.getAllMonitors();
for (let i = 0; i < monitors.length; i++) {
if (i % JOBS_PER_WORKER === 0) {
const worker = createWorker(queue);
worker && workers.push(worker);
}
enqueueJob(queue, monitors[i]);
}
// Make sure a worker was created, none will be created if jobs < JOBS_PER_WORKER
if (workers.length === 0) {
const worker = createWorker(queue);
worker && workers.push(worker);
if (!worker) {
logger.error("Failed to create workers", { service: SERVICE_NAME });
}
}
};
const cleanup = async () => {
try {
logger.info("Cleaning up Ping Service...", { service: SERVICE_NAME });
// Clean out the queue
const jobs = await queue.getJobs(["active", "waiting", "delayed"]);
// There could be a great many jobs, handle this asynchronously with Promise.all
await Promise.all(jobs.map((job) => job.remove()));
// Close workers. Same as jobs, there could be many workers we don't want to wait for each one to close.
await Promise.all(workers.map((worker) => worker.close()));
// Close the queue
await queue.close();
logger.info("Ping Service cleaned up", { service: SERVICE_NAME });
} catch (error) {
logger.error(error.message, { service: SERVICE_NAME });
}
};
module.exports = { startPingService, cleanup };