www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - What makes vibe.d Incredibly Slow on a VPS?

reply seany <seany uni-bonn.de> writes:
Consider this fraction of code Please:



         void createNewOwner(HTTPServerRequest req, 
HTTPServerResponse res)     {	
     	    writeln("NEW OWNER requests are : -----");
     																							    writeln(req.form);
     																							writeln(req.files); 
writeln("==============");


     	// TASK EXTRACT the data from the POST variable// 
--------------------------------------------------------------------------------------------------------------//
     	// TODO check security with req.form["loginToken"];

     	string avatarPath ;

     	if( req.files.length != 0) {													
                     // HERE we only check if file is supplied...
     		// no "existing avatar" yet, as fresh new user.

     		auto file = "file" in req.files;

     		if (file.filename != "" ) {

     		string k = genNonce();												// Generate a random 
number to ensure there is no conflict

     			string rp = req.form["username"].replace(" ", 
"-").replace(" ", "-")~"-"~k~"-"~(file.filename.name).replace(" 
", "-").replace(" ", "-");
     																							// replaced spaces with "-" and   with 
-, to avoid loading problems
     			try {

     				moveFile(file.tempPath.toString(), 
"assets/images/avatars/" ~ rp);			writeln("Uploaded 
successfully!");
     				avatarPath = "/" ~ "assets/images/avatars/" ~ rp;
     			} catch (Exception e) {
     																							writeln("Exception thrown, trying 
copy");
     				copyFile(file.tempPath.toString(), 
"assets/images/avatars/" ~ rp);
     				avatarPath = "/" ~ "assets/images/avatars/" ~ rp;
     			}
     		}
     	} else {

     		avatarPath = 
"assets/images/avatars/noFace.png";										// Here it is 
allowed. IF no image, then set a default.
     	}


     	avatarPath = avatarPath.replace(" ", "");													// 
should not be needed, but just in case
     	avatarPath = avatarPath.replace(" ", "-");

     	string e2fa = "";
     	req.form["en2fa"] == "true" ? (e2fa = "1") : (e2fa = 
"0");								// converted e2FA to 0 or 1, in string format


     	// TASK confirm no conclict // 
----------------------------------------------------------------------------------------------------------------------------------//

     	auto check_existingUser = loginRoutines.get_userAllInfo( 
req.form["username"]);

     	if (check_existingUser.length != 0) {														// 
username already exists.... The only valid value here is 0
     																							// = no records. anything  != 0 will 
be rejected

     		res.writeBody("ERROR: 30LX-USEREX. Username existiert 
schon... Verwenden Sie bitte einen anderen Username.");
     		return;
     	}



     	// TASK set entry details // 
------------------------------------------------------------------------------------------------------------------------------------//

     	int usrCnt  = 
loginRoutines.get_userCount();												write("user count is: 
"); writeln(usrCnt);
     	if (usrCnt < 0) {
     		res.writeBody("ERROR: 71QM-UKNDBR. Unbekannter 
Datenbankfehler. Versuchen Sie später erneut.");
     		return;

     	}
     	string cntr = to!string(usrCnt +1);														// next 
item in file.

     	string[string] nuInfo ;																	// container for new 
user Info

     	nuInfo["username"] 	= req.form["username"];
     	nuInfo["fName"]		= req.form["fName"];
     	nuInfo["lName"]		= req.form["lName"];
     	nuInfo["avatarPath"]= avatarPath;
     	nuInfo["mail"]		= req.form["mail"];
     	nuInfo["tel"]		= req.form["tel"];
     	nuInfo["mob"]		= req.form["mob"];


     	string[string] lgInfo;

     	lgInfo["username"]	= req.form["username"];
     	lgInfo["role"]		= "owner";
     	lgInfo["active"]	= "-1";																	write("going to add 
signUp line in user dtls : "); writeln(lgInfo);


     	string loginInfo = cntr ~ "," ~ req.form["username"] ~ "," ~ 
"++++++++++++++++++++++" ~ "," ~ e2fa ~ ", 0";
     																							// enter new user with supplied 2FA, 
but set the last field = 0,
     																							// as not yet paired.



     	// TASK insert the data // 
--------------------------------------------------------------------------------------------------------------------------------------//


     	bool stat;																				write("going to add signUp 
line in owner dtls : "); writeln(nuInfo);
     	stat = databaseRoutines.add_newRecord(nuInfo, 
"data/ownerDTLS.db");
     																							write("User INFORMATION insertion 
success : "); writeln(stat);
     	if (! stat) {
     		res.writeBody("ERROR: 35TG-DTLSER. Das erstellen vom 
eingegebenen User war nicht erfolgreich. Bitte versuchen sie 
später erneut.");
     		return;
     	}


     	stat = databaseRoutines.add_newRecord(lgInfo, 
"data/userRoles.db");
     																							write("User ROLE insertion success : 
"); writeln(stat);
     	if (! stat) {
     		res.writeBody("ERROR: 36TG-ROLEER. Das erstellen vom 
eingegebenen User war nicht erfolgreich. Bitte versuchen sie 
später erneut.");
     		return;
     	}




     	stat = 
loginRoutines.write_loginDtls(loginInfo);											write("User 
login insertion success : "); writeln(stat);
     	if (! stat) {
     				res.writeBody("ERROR: 37TG-LGINER. Das erstellen vom 
eingegebenen User war nicht erfolgreich. Bitte versuchen sie 
später erneut.");
     				return;
     	}


     	string command = "bash mail.sh "~nuInfo["mail"]~" 
"~nuInfo["mail"];						write("Executing : "); writeln(command);

     	auto ml = executeShell("bash mail.sh "~nuInfo["mail"]~" 
"~nuInfo["mail"]);					writeln("mail has been sent .... ");
     																							writeln(ml.status);
     																							writeln(ml.output);


     	// TASK create a new file // 
------------------------------------------------------------------------------------------------------------------------------------//


     	stat = 
databaseRoutines.create_newDatabase("data/history-"~req.form["username"]~
".db", "username, timeString, text, label");
     																							write("history file creation success: 
");writeln(stat);
     	if (! stat) {
     		res.writeBody("ERROR: 38TG-NOHSTR. Das erstellen vom 
eingegebenen User war nicht erfolgreich. Kontaktieren Sie den 
Administrator.");
     		return;
     	}																						// file at Path with scheme is created

     	string[string] hist;

     	SysTime nowTime = Clock.currTime();

     	string timeStr = 	to!string(nowTime.day) ~"." ~
     					to!string(nowTime.month) ~"."~
     					to!string(nowTime.year) ~"."~ " "~
     					to!string(nowTime.hour) ~":"~
     					to!string(nowTime.minute) ;

     	hist["username"]	= req.form["username"];
     	hist["timeString"]	= timeStr;
     	hist["text"]		= "User wurde Angelegt";
     	hist["label"]		= "2";

     	stat = databaseRoutines.add_newRecord(hist, 
"data/history-"~req.form["username"]~ ".db"); write("history file 
creation success: ");writeln(stat);

     	if (! stat) {
     		res.writeBody("ERROR: 39TG-HSTRER. Das erstellen vom 
eingegebenen User war nicht erfolgreich. Kontaktieren Sie den 
Administrator.");
     		return;
     	}																						// record added


     	res.writeBody("Eine Email wurde versandt, um das Onboarding 
fertigzustellen. " );

          }


Basically, I am trying to add some Records in a File. It works on 
my localhost.

But on a VPS server, the program outputs the first writeln line 
(not even the consequent req.form printouts), then apparently 
stops for several seconds ( 10 to 16) , and then suddenly starts 
working again. I see this in the log outputs.

Why does this happen? How can I start debugging?

thank You
Mar 18 2023
parent Steven Schveighoffer <schveiguy gmail.com> writes:
On 3/18/23 9:36 AM, seany wrote:

 But on a VPS server, the program outputs the first writeln line (not 
 even the consequent req.form printouts), then apparently stops for 
 several seconds ( 10 to 16) , and then suddenly starts working again. I 
 see this in the log outputs.
 
 Why does this happen? How can I start debugging?
Before getting into it any further, try flushing output after every writeln. This is true in D and C too -- if your `stdout` stream is connected to a log file, it will *not* flush upon every newline. However, if it's connected to a terminal, it *will* flush upon every newline. It's possible it is running just as fast as you expect, but the buffered output has not yet been flushed. So just add `stdout.flush()` after every `writeln` call and see if it helps. If not, then it needs more investigation. -Steve
Mar 18 2023