Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parse Server handles cloud code request sequentially #3696

Closed
zack1991 opened this issue Apr 6, 2017 · 8 comments
Closed

Parse Server handles cloud code request sequentially #3696

zack1991 opened this issue Apr 6, 2017 · 8 comments

Comments

@zack1991
Copy link

zack1991 commented Apr 6, 2017

Hi, I am using parse server on my stand alone server(rackspace) for my game. When calling cloud functions from its response time is high takes to much time, sometime it gives response in 20 sec. Currently only 4-5 users are playing.

Server Configuaration : Rackspace server, 4 GB RAM
DB Server : Mongo Atlas, 2GB RAM

When i am using sleep in my parse cloud code then call to my all cloud function gets stcuked. Its handling cloud code request sequentially. Can you please explain the steps to configure my parse server to handles cloud code request parallally.

I am writing client code of game in Unity and JS.

Thanks

@flovilmart
Copy link
Contributor

nodejs/expressjs should process the request in 'parallel', but parallel is not the parallel you may think.

nodejs being event driven, when a request arrives to the server, there is no guarantee that this request will be processed immediately, if the runloop is already busy processing another request.

Given the amount of ram you have on your server, you can probably start with the cluster option (if using the CLI)

Otherwise you can use PM2, which would be able to spawn multiple nodejs processes on your instance and allow for higher concurrency.

Also, that seems odd that your functions take 20s to respond, did you check the indexes in the mongo database?

@steven-supersolid
Copy link
Contributor

Whenever there is a cloud code request that calls a database function a HTTP request is made from the server back to itself. The default path for this is on localhost so without clustering it will block other requests.

You should check your mongo logs for slow queries first as suggested, but also clustering is a must when using cloud code. Even with clustering you can expect a very few requests to be stalled. You can also try enabling direct access which removes the HTTP request step. This can be done by setting the environment variable PARSE_SERVER_ENABLE_EXPERIMENTAL_DIRECT_ACCESS to 1.

@zack1991
Copy link
Author

zack1991 commented Apr 7, 2017

Below is the my code -

Parse.Cloud.define("ping", function (req, res) {
try {
if (req.user !== undefined) {
//console.log("User Name--------> " + req.user.get("username"));
//console.log("User--------> " + JSON.stringify(req.user));
//update session update_at time
LoginHelper.updateSessionUpdateTime(req, function (error, sessionData) {
if (error) {
res.success({result: 0, custom_error_code: error.code, custom_error_message: error.message, stacktrace: error.stack});
} else {
sleep(30000);
res.success({result: 1});
}
});
} else {
res.success({result: 0, custom_error_code: CustomErrorCode.INVALID_USER_ERROR, custom_error_message: "Inavalid user"});
}
} catch (e) {
res.success({result: 0, custom_error_code: e.code, custom_error_message: e.message, stacktrace: e.stack});
} finally {
console.log("==================================");
}

});

function sleep(time, callback) {
var stop = new Date().getTime();
while(new Date().getTime() < stop + time) {
;
}
callback();
}

When ping cloud function gets called then other cloud calls from any user gets stucked untill sleeps time complete. There is solution other than cluster to solve this problem. Without making any change in my code.

@flovilmart
Copy link
Contributor

The problem is your sleep method, you're blocking the whole event loop with your while.

you should probably replace

sleep(30000);
res.success({result: 1});

by

setTimeout(function() {
  res.success({result: 1});
}, 30000) // wait 30 seconds

@zack1991
Copy link
Author

zack1991 commented Apr 7, 2017

Ok Fine, Now i just remove the sleep code, I am calling ping request from js sdk client at every 15 seconds its response time is showing sometimes more than 5 seconds , i have set condition on response if response not come in 5 seconds then show week signal. There is any method to improve the performance of parse server and reduced the response time of ping or any cloud request.

@flovilmart
Copy link
Contributor

I'm not sure what your 'LoginHelper.updateSessionUpdateTime' does but you should probably check what's in it and why it takes so much time.

Before pinning 'on parse-server' the time it takes to respond, you can try to remove your custom code and see the baseline for such requests.

you should be able to serve millions of requests per day with parse-server and respond well below 100ms.

@zack1991
Copy link
Author

Below is my ping cloud code :-

main.js

//Ping request from client
Parse.Cloud.define("ping", function (req, res) {
try {
if (req.user !== undefined) {
if (!req.params.hasOwnProperty(GameConstants.USER_ID)) {
req.params.user_id = req.user.get("username");
}
LoginHelper.updateUserSessionEndDateTime(req, function (error, gameUser) {
if (error) {
res.success({result: 0, custom_error_code: error.code, custom_error_message: error.message, stacktrace: error.stack});
} else {
res.success({result: 1});
}
});
} else {
res.success({result: 0, custom_error_code: CustomErrorCode.INVALID_USER_ERROR, custom_error_message: "Inavalid user"});
}
} catch (e) {
res.success({result: 0, custom_error_code: e.code, custom_error_message: e.message, stacktrace: e.stack});
} finally {
console.log("======ping=========");
}

});

LoginHelper.js

updateUserSessionEndDateTime: function (req, callback) {
var query = new Parse.Query(Parse.Object.extend(GameConstants.GAME_USERS));
query.select("session_end_date_time");
query.equalTo(GameConstants.OBJECT_ID, req.params.user_id);
query.first({
success: function (gameUser) {
if (typeof gameUser !== "undefined") {
console.log("updateUserSessionEndDateTime data===========> " + JSON.stringify(gameUser));
gameUser.set(GameConstants.SESSION_END_DATE_TIME, new Date());
gameUser.save(null, {
success: function (gameUser) {
console.log("updateUserSessionEndDateTime.save.success===========> " + JSON.stringify(gameUser));
callback(null, gameUser);
},
error: function (error) {
console.log("updateUserSessionEndDateTime.save.error===========> " + error.message);
callback(error);
}
});
} else {
console.log("updateUserSessionEndDateTime.sessionData-------> undefined ");
callback(null, null);
}
},
error: function (error) {
console.log("updateUserSessionEndDateTime.error===========> " + error.message);
callback(error);
}
});
}

Now i am checking the performance of parse server with js client by sending 1000 ping request from client :-
for (var i = 0; i < 1000; i++) {
ping();
console.log("Ping-------> " + i);
}

function ping() {
//debugger;
Parse.Cloud.run("ping", {app_id: "1085075762"}, {
success: function (result) {
// Show result as an alert
console.log(result);
},
error: function (error) {
//debugger;
console.log("ping=======>Error code----------> " + error.code + ", Error message----------> " + error.message);
}
});
}

ping response

My last ping request response comes in 55.65 sec. Why parse server is not handling the request very fast.

@flovilmart
Copy link
Contributor

I believe I answered a similar issue somewhere else

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants