Question about using the module when a NodeJS+Express simultaneous request is received.

Asked 2 years ago, Updated 2 years ago, 116 views

Hello, I am currently running the Express app using AWS Lambda. I have a question about NodeJS, which is based on Single Thread.

// dateUtil.js
"use strict";
var DateUtil = (function () {
    function DateUtil() {
        console.log('created');
    }
    DateUtil.prototype.dateToTime = function (dateObject) {
        var date = dateObject.getTime();
        return date;
    };
    return DateUtil;
}());
exports.default = new DateUtil();
// app.js
var express = require('express');
var dateUtil = require('./dateUtil')
var app = express();
var server = app.listen(3000, function(){
    console.log("Express server has started on port 3000")
})

When the actual app is uploaded to the server and users A and B access it, dateUtil is shared with each other.(created once)

In other languages, the server was multi-threading, so I didn't care about sharing memory between users. I have a question here.

If you import the module function to import like dateUtil above, within the route If multiple users use the module at the same time, is there a possibility that the data inside the function will also be shared? (If the above code is simple but has a lot of actual variables and logic)

Or is there no concern because each stack memory is allocated for each user when calling the actual function?

Actually, I tried many things with sleep, but it wasn't shared, but I couldn't find it theoretically, so I'm leaving a question.

node.js express

2022-09-22 15:53

2 Answers

I ask for your understanding in advance.

Please read and judge if I understand the gist of the question well.

It may not be what you want.

Let's add some to the code you wrote.

// Add
var count = 0;

var DateUtil = (function () {
    function DateUtil() {
        console.log('created');
    }
    DateUtil.prototype.dateToTime = function (dateObject) {
        var date = dateObject.getTime();
        return date;
    };
    // More
    DateUtil.prototype.getCount = function () {
        return count++;
    };
    return DateUtil;
}());

// Change for convenience
exports = new DateUtil();

And I'll sing it on app.js.

for (var i = 0; i < 100; i++) {
    var dateUtil = require('./dateUtil');
    console.log(dataUtil.getCount());
}

What will happen?

0 to 99. DataUtil Sharing the declared variable value in the module scope.

So

var DateUtil = (function () {
    // Change location to here
    var count = 0;
    function DateUtil() {
        console.log('created');
    }
    DateUtil.prototype.dateToTime = function (dateObject) {
        var date = dateObject.getTime();
        return date;
    };
    DateUtil.prototype.getCount = function () {
        return count++;
    };
    return DateUtil;
}());

exports = new DateUtil();

What happens if I change it like this?

But it's going to go from 0 to 99. The above module has already returned an instance and the app.js that you use receives exactly the first instance you created. Every time you do require, you don't pull out a new instance. Eventually, I'm writing one count.

In the end, if you have to give a different instance for each user connection,

Class exports so that you can instantiate every connection I think it's right to instantiate and use it directly on a controller such as app.js.

function DateUtil() {
    console.log('created');
}
DateUtil.prototype.dateToTime = function (dateObject) {
    var date = dateObject.getTime();
    return date;
};

exports = DateUtil;
//app.js

var DateUtil = require('./DateUtil');

function blahblah (user) {
    //...
    var du = new DateUtil();
    user.updateDate = du.dateToTime(obj);
    //...
}

Like this?

The above just shows that each user can view the same resources declared in a particular module.

To tell you the conclusion apart from the above, I don't think we need to worry about data loss caused by multi-threading and shared resources.

As you said, it is a single thread, so it will proceed in the order of accumulation in the call stack, so there will be no problem when r/w by accessing resources such as count simultaneously.


2022-09-22 15:53

aws lambda the drive to the container.

If there is no request for a period of time (approximately 5 minutes), the container will be closed.

This is because the response is late when there is a re-request (cold start). In other words, you should not save the status light because it is stateless, but if you request the same gun container at multiple requests, you will receive the stored data (that is, it will be shared).

It's either a yes or a no, but I think there could be confusion.

aws lambda is a fully managed service that becomes an auto-scaling light. When traffic is concentrated on the lambda developed by the questioner, the auto-scale is carried out, and the data of the newly created container is naturally initialized. Status sharing between containers is not possible.

In summary, you should not share any data or status through Lambda.

External storage services such as dynamodb, rds, elasticache, and s3 should be used to share the status, session, and data that needs to be changed.


2022-09-22 15:53

If you have any answers or tips


© 2024 OneMinuteCode. All rights reserved.