I have a site, implemented on NodeJS, base MongoDB, Mongoose plugin. Recently, the site began to fall about once a day. I recently found out that this is due to the lack of memory, which is due to the fact that active connections are being accumulated (db.serverStatus (). Connections.current). Perhaps this is not related, but I have a script on NodeJS, which is executed by crown every minute. It checks if there is a post with the current date in the documents. But I close the mongoose connection there, I don’t know what could be the problem. Actually this file contents:
process.env.NODE_TLS_REJECT_UNAUTHORIZED = 0;
const { new_time } = require("lib/functions");
const push = require("lib/push");
const apiCallback = require("middleware/socket/apiCallback");
const mongoose = require("lib/mongoose");
const User = require("models/User");
const Post = require("models/Post");
(async () => {
let currentPost = await Post.findCurrent(1);
if (currentPost) {
await currentPost.setPublished(1);
await apiCallback.call({
roomName: "index",
event : "posts.new",
data : {
post: {
id: currentPost._id.toString()
}
}
});
await push.sendAll({
// unnecessary data
});
}
await mongoose.connection.close();
process.exit(0);
})();
app.js:
const path = require("path");
const express = require("express");
const app = express();
const bodyParser = require("body-parser");
const cookieParser = require("cookie-parser");
const expressSession = require("express-session");
const MongoStore = require("connect-mongo")(expressSession);
const conf = require("conf");
const mongoose = require("lib/mongoose");
const expressSessionConfig = conf.get("session");
expressSessionConfig.cookie.expires = new Date(new Date().getTime() + 60 * 60 * 24 * 30 * 1000);
expressSessionConfig.store = new MongoStore({
mongooseConnection: mongoose.connection
});
const templateDir = path.join(__dirname, conf.get("template_dir"));
app.engine("ejs", require("ejs-locals"));
app.set("views", templateDir);
app.set("view engine", "ejs")
app.use(express.static("frontend"));
app.use(cookieParser());
app.use(expressSession(expressSessionConfig));
app.use(bodyParser.urlencoded({
extended: true
}));
require("routes")(app);
app.listen(conf.get("app_port"));
app.io.js (socket server on socket.io):
const fs = require("fs");
const path = require("path");
const app = require("express")();
const bodyParser = require("body-parser");
const apiCallback = require("middleware/socket/apiCallback");
const conf = require("conf");
const sslPath = conf.get("sslPath");
const sslOptions = {
key : fs.readFileSync(path.join(sslPath, "key.key")),
cert: fs.readFileSync(path.join(sslPath, "crt.crt"))
};
const server = require("https").Server(sslOptions, app);
const io = require("socket.io")(server);
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(conf.get("api_callback:path"), apiCallback.watch(io));
require("routes/socket")(io);
server.listen(conf.get("socket_port"));
routes/socket.js:
const { in_array } = require("lib/functions");
const loadUser = require("middleware/socket/loadUser");
const User = require("models/User");
module.exports = io => {
io.on("connection", async socket => {
let query = socket.handshake.query || {};
let { ssid } = query;
ssid = ssid || "";
let user = socket.user = await loadUser(ssid);
let oldPageName = null;
User.setOnline(user._id, 1);
socket.on("setPageName", pageName => {
if (oldPageName) socket.leave(oldPageName);
oldPageName = pageName;
socket.join(pageName);
});
socket.on("disconnect", () => {
socket.leave(oldPageName);
User.setOnline(user._id, 0);
});
});
};
Tell me how to properly close connections so that they do not remain in memory and do not load the server to such an extent that it kills the process of the MongoDB daemon?
your code has no issues, you should go for connection pooling. your issue would automatically resolve. you will have a pool of connections whenever any api needs a db conenction. connection would be picked up from the pool and after completing db operation connection wouldn't be destroyed instead it would be returned back to the pool, in this manner your product's performance would be increased along with resolution to this issue.
https://mongoosejs.com/docs/connections.html
Related
I am trying to impliment websocket server for my frontend chart for trading values but whenever i try to change graph pairs its fluctuating my frontend and not clearing privious request here's my server file
const express = require('express');
const path = require('path');
const mysql = require('mysql')
const bodyParser = require('body-parser');
const passport = require('passport');
const exchangeCtrl = require("./controllers/exchange.controller.js");
const webSocketServer = require("websocket").server;
const cors = require("cors");
const app = express();
app.use(cors());
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());
app.use('/static', express.static('public'))
const port = 8000;
var server = app.listen(port, () => console.log(`Server up and running on port
${port} !`));
const wsServer = new webSocketServer({
noServer: true,
path: "/websockets",
httpServer: server,
});
const client = {};
const getUniqueId = () => {
const s4 = () =>
Math.floor((1 + Math.random()) * 0x10000)
.toString(16)
.substring(1);
return s4() + "-" + s4() + "-" + s4();
};
var socketDataVar = "";
wsServer.on("request", function (request) {
var userUd = getUniqueId();
const connection = request.accept(null, request.origin);
client[userUd] = connection;
client[userUd].send(JSON.stringify(userUd));
connection.on("message", async function (message) {
var interval = 1000;
if (message.type === "utf8") {
if (message.utf8Data) {
if (JSON.parse(message.utf8Data) == "disconnect") {
clearInterval(socketDataVar);
} else {
socketDataVar = setInterval(
() => socketData(message.utf8Data),
interval
);
}
}
}
});
const socketData = async (socket) => {
var value = JSON.parse(socket);
var firstCoinId = value.firstCoinId;
var secondCoinId = value.secondCoinId;
var userId = value.userId;
var clientId = value.clientId;
var graphDataApi = await exchangeCtrl.graphData(firstCoinId, secondCoinId);
var topBarApi = await exchangeCtrl.topBar(firstCoinId, secondCoinId);
var filalData = {
graphDataApi,
topBarApi
};
for (key in client) {
client[key].sendUTF(JSON.stringify(filalData));
}
};
});
I am trying to clear the interval and then set the new values but i might think that its not working and i get 2 set of data on each click of frontend
I'm just getting used to NodeJS and MongoDB so please go gentle! I'm trying to "console.log" the "network Interfaces" to find the IP address.
No matter what I do, I keep getting an error:
"TypeError: Cannot read property '1' of undefined "
I suspect that it's this code in line 11:
const ip = networkInterfaces.Ethernet[1].address;
Here is what is in my app.js file:
const express = require("express");
const app = express();
const mongoose = require("mongoose");
const morgan = require("morgan");
const bodyParser = require("body-parser");
const path = require("path");
const cors = require("cors");
const os = require("os");
const networkInterfaces = os.networkInterfaces();
const ip = networkInterfaces.Ethernet[1].address;
require("dotenv/config");
//import routes
const productRoute = require("./routes/product");
const cartRoute = require("./routes/cart");
const orderRoute = require("./routes/order");
const favoriteRoute = require("./routes/favorite");
const authRoute = require("./routes/auth");
const notification = require("./middlewares/pushNotification");
//Connect to DB
const dbURI = process.env.DB_CONNECTION;
mongoose.connect(
dbURI,
{
useNewUrlParser: true,
useUnifiedTopology: true,
useFindAndModify: false,
useCreateIndex: true,
},
() => {
app.listen(process.env.PORT, ip);
let dirPath = path.join(
__dirname,
"public/api/static/images/productPictures"
);
let dirPathUser = path.join(
__dirname,
"public/api/static/images/userprofile"
);
createDir(dirPath);
createDir(dirPathUser);
console.log("Connected to DB");
}
);
function createDir(dirPath) {
if (!fs.existsSync(dirPath)) {
fs.mkdirSync(dirPath, { recursive: true }, (err) => {
if (err) {
console.error("createDir Error:", err);
} else {
console.log("Directory is made!");
}
});
}
}
...
this answer will help you with
network interfaces
If you are trying to get the client IP then you can use
const RequestIp = require("#supercharge/request-ip");
const ip = RequestIp.getClientIp(req);
inside your API
or to get the current machine address you can use child process
I solved the issue by removing Ethernet[1].address with en0[1].
line 11 now reads:
const ip = networkInterfaces.en0[1].address;
I added this to the end of my App.js files:
const port = process.env.PORT || '3000';
const address = process.env.ADDRESS || '127.0.0.1';
app.listen(port,address, () => console.log('Server running on http:// ' + address + ':' + port +'/'));
I have been getting a problem when I want to module.export the pool variable to use it in other files. I have this program in src\db\index.js:
const {Pool} = require('pg');
const express = require('express');
//Initialize
const path = require('path');
const app = express();
const fetch = require('fetch');
const PORT = process.env.PORT || 5000;
//Global Variables
const pool = new Pool({
connectionString: process.env.DATABASE_URL,
ssl:true
});
//Setting
app.use(express.static(path.join(__dirname, 'public')));
//Routes
app.use(require('../Routes/logIn'));
app.use(require('../Routes/singIn'));
app.use(require('../Routes/forgotPass.js'));
app.listen(PORT, () => console.log(`Listening on ${PORT}`));
module.exports = pool;
And then I want to require the const pool in this file src\Routes\LogIn.js:
const express = require('express');
const pool = require('../db');
const router = express.Router();
router.get('/usuario/:user', function (req, res) {
//console.log("GET usuario");
var user = req.params.user;
pool.query(
`select * from users where email = '${user}' limit 1`,
function (error, resq, fields) {
if (error) {
console.log(error);
} else {
console.log(user);
res.send(resq.rows);
}
}
);
});
module.exports = router;
But when I run the index.js and go to the route ulr/usuario/:user, in the logs I see that the program has an error that says "pool.query is not a function". I want to know how i could export the const pool to use it in other files.
You can use
module.exports = {
query: (text, params) => pool.query(text, params),
}
Use express-promise-router
const Router = require('express-promise-router')
const db = require('../db')
const router = new Router()
Use
await db.query(`
SELECT * from local
`)
instead of pool.query in your router.get or router.post
The above should solve your issue - You can check the same reference here
https://node-postgres.com/guides/async-express
We are having a simple json-server setup, loading it as a module.
However, when making a POST/PUT request, the data is not being injected into the db.json.
const jsonServer = require("json-server");
const source = require("./db.json");
const repl = require("replify");
const bodyParser = require("body-parser");
const paginationMiddleware = require("./middlewares/pagination");
const filterByAccessRightFor = require("./middlewares/filterByAccessRightFor");
const searchMiddleware = require("./middlewares/search");
const delayMiddleware = require("./middlewares/delay");
const createdAt = require("./middlewares/created_at");
const daterange = require("./middlewares/daterange");
const absence = require("./middlewares/absence");
const bankAccount = require("./middlewares/bankAccount");
const sort = require("./middlewares/sort");
const fileUpload = require("express-fileupload");
const withUser = require("./responseEnhancers/withUser");
const withAbsenceType = require("./responseEnhancers/withAbsenceType");
const withIndexData = require("./responseEnhancers/withIndexData");
const withNationalStateHolidayOverride = require("./responseEnhancers/withNationalStateHolidayOverride");
const withRoleRestrictions = require("./responseEnhancers/withRoleRestrictions");
const compose = require("lodash/fp/compose");
const initSickImagesEndpoint = require("./features/sicks/images/initEndpoint");
const initLoginEndpoint = require("./features/login/initEndpoint");
const path = require("path");
const express = require("express");
const createCalendarEntry = require("./_helpers/createCalendarEntry");
process.on("createCalendarEntry", createCalendarEntry);
const server = jsonServer.create();
const defaultMiddlewares = jsonServer.defaults({
static: path.join(path.resolve(process.cwd()), "server", "files")
});
const router = jsonServer.router(source, {
foreignKeySuffix: "_id"
});
router.render = (req, res) => {
res = compose(
withIndexData(req),
withUser,
withAbsenceType,
withNationalStateHolidayOverride(req),
withRoleRestrictions(req, db)
)(res);
res.jsonp(res.locals.data);
};
const db = router.db;
if (process.env.NODE_ENV === "production")
server.use(express.static(path.join(__dirname, "../build")));
server
.use(
jsonServer.rewriter({
"/de/*": "/$1"
})
)
.use(bodyParser.json())
.use(fileUpload())
.use(defaultMiddlewares)
.use(paginationMiddleware)
.use(searchMiddleware)
.use(delayMiddleware)
.use(createdAt)
.use(daterange)
.use(absence)
.use(bankAccount)
.use(sort);
initLoginEndpoint(server, db);
initSickImagesEndpoint(server, db);
server.route("/sicks").all(filterByAccessRightFor(db));
server.route("/vacations").all(filterByAccessRightFor(db));
server.use(router);
server.listen(3001, "0.0.0.0", () => {
console.log("JSON Server is running");
});
repl("db", server, { db });
exports.db = db;
module.exports = server;
This is our index.js and apart from the db.json not updating, everything is working fine as expected. We have a script that is seeding the db, and when accessing a resource via GET the correct data gets retrieved.
Any ideas on that one?
Instead of providing a JSON object using require for the db.json file, you should provide a path to the json file.
// const source = require("./db.json");
const source = path.join(__dirname, 'db.json')
const router = jsonServer.router(source, {
foreignKeySuffix: "_id"
});
I would like to get an 'articlePageId' number from url as below, but the terminal window did not show the URL query parameters...
What's the matter with my coding?
Could anyone tell me how can I do that??
Thank you very much.
I have tried the following:
https://localhost:8090/articlePage.html?articlePageId='+item.ID
console.log(fullUrl) // http://localhost:8090/
console.log(req.path) // /
console.log(req.params) // {}
console.log(req.query.articlePageId) // undefined
Here is the Server
const express = require('express');
const expressStatic = require('express-static')
const bodyParser = require('body-parser');
const cookieParser = require('cookie-parser');
const cookieSession = require('cookie-session');
const multer = require('multer');
const multerObj = multer({dest:'./static/upload'});
const consolidate = require('consolidate');
const server = express();
server.use(bodyParser.urlencoded({extended:true}));
server.use(multerObj.any());
server.use(cookieParser());
(function(){
const keys = [];
for(var i=0;i<1100000;i++){
keys[i] = 's_' + Math.random();
}
server.use(cookieSession({
keys,
name:'sess_id',
maxAge:20*60*1000
}));
})()
server.engine('html',consolidate.ejs);
server.set('views','template');
server.set('view engine','html');
server.use('/',require('./router/web/index')());
server.use('/admin',require('./router/admin/index')());
server.use(expressStatic('./static/'))
server.listen(8090)
Here is the index.js
router.use('/', require('./articlePage')())
Here is the articlePage.js
var express = require('express');
var mysql = require('mysql');
var urlLib = require('url');
var querystring = require('querystring')
var db = mysql.createPool({
localhost: 'localhost',
user: 'root',
password: '123456',
database: 'blog'
})
module.exports = () => {
var router = express.Router();
router.get('/', (req, res) => {
var fullUrl = req.protocol + '://' + req.get('host') +req.originalUrl;
console.log(fullUrl)
console.log(req.path)
console.log(req.params)
console.log(req.query.articlePageId)
db.query(`SELECT * FROM articles_table WHERE ID='articlePageId'`, (err, page) =>
{
if (err) {
console.error(err);
res.status(500).send('database error').end();
} else {
res.send(page);
}
})
})
return router
}