Forum Moderators: coopster

Message Too Old, No Replies

I need a fresh pair of eyes

Can I have another perspective on this:-

         

Matthew1980

7:41 pm on Oct 14, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Hi there people of the forum,


var $ConnectionAttempts = 4;
var $conn;


function connect(){

for($i=0; $i<$this->ConnectionAttempts; $i++){
$this->conn = mysql_connect($this->DBhost,$this->DBuser,$this->DBpass);

if($this->conn){
return $this->conn;
break;
}

if($i <> $this->ConnectionAttempts){
$this->PipeError(mysql_error());
header("location: ./path/to/somefiles/ConnectingError.php");
exit;
}
}
}


I think as this works, no, I hope it works, at least it seems to! Basically what I want is for the connect() to try 4 times to establish a connection to the MySql DB, obviously if it connects first time, return the resource #id as a property of the function/method, which I think it does, BUT if it fails for some reason, keep trying until it does. Then if it reaches the limit, I pipe the error message (text file below root of server) and then redirect to a 'Holding page' with a nice friendly message.

The only thing I am thinking of adding is: if(($i <> $this->ConnectionAttempts) || (!$this->conn = NULL)) but I'm not sure, I mean I can't tell if it actually does anything...

That's how I think I have written it to work, but after a long day at work doing VB6/.NET I would like the benefit of a new perspective.

Thanks,
MRb

httpwebwitch

9:00 pm on Oct 14, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



My head is in PHP mode now, so I apologize if syntax is inaccurate

1) no need to break after returning. return ends the function immediately.
2) the for loop will end after ConnectionAttempts times. you don't need to check within the loop if you're at the end of the loop. Just let the loop end, then do your "plan b" because at that point you would have returned if $conn was successful.
3) I would add a little delay between each attempt with a little sleep.



function connect(){

for($i=0;$i<$ConnectionAttempts;$i++){
$conn = mysql_connect(blah blah blah);
if($conn){
return $conn;
}
sleep(1);
}

// well at least you tried.
// redirect to your failwhale page
die();
}


I must ask: why is this necessary? If you can't connect to a database, the database is broken. If it's broken, you need to fix the database server. I'd attempt one connection, and if that fails, show something apologetic to the user, and send a panic notification to the DB admin.

Launching code that tries 4 times is like giving permission to the db server not to work 3 times.

If you insist on trying 4 times - so that your app code is robust and failproof - send out a panic alarm on the 1st failed attempt.

Matthew1980

9:13 pm on Oct 14, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Hi there httpwebwitch,

Wow! PHP mode is active alright! I have another function that I was referencing when I did this, and it has a break in it, and at the time, having the break there made sense, so thanks for alerting me to that - I must admit though as I didn't know as return acted as a ~sort of~ exit; That's one to remember.

>>I must ask: why is this necessary?

Well, I know of a situation that this scenario happens, and as I am working on an intranet task scheduler for our test department, I thought I would use the same logic - and I know for a fact that this sql server has a heavy load on it for most of the day (purchase requestions being processed etc) so I would rather try a few attempts then at least the user wouldn't know as they had been in a que (I think that's what sql engines do anyway when there are simultaneous queries being made).

But having stated that I do agree with you if it was in the public domain, after all I would be paying for that service from a big hosting company, so it would be good to keep them on their toes!

Cheers,
MRb

httpwebwitch

2:02 am on Oct 15, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I use "return" liberally as an exit point of a function, like:

function attempt_something(){
if($bad_input){return false;}
if($bad_timing){return false;}
while(waiting_for_godot()){
if($lost_patience){
return false;
}
}

// if you've reached this point, then you can go ahead and do something complex
$success = do_something_complex()
return $success;
}

knowing that "return" is an immediate abort from any function, you'll find that you use the "else" part of "if-else" conditions less often, and code becomes less tangly.

As for the reasoning behind multiple attempts... I'll offer a metaphor: I can install solar panels on the roof, install a new energy star furnace, double-pane all my windows, switch to CFL bulbs and reinsulate the attic... but really the most effective way to lower my energy bills is to teach my kids to stop leaving the effing back door open all the time. What I mean is, you can put massive amounts of effort into a solution, and find that you were solving the wrong problem.

If your SQL server is so taxed that *one more connection* is enough to max it out, or if the SQL is already so maxed that it can't handle one more query, then the problem is with your SQL server, not your application code. Say you have 499 connections in there, and you try to put a 500th in, and it doesn't connect. Is that reasonable? If 499 is a normal load, then why is the limit set to 500? Rule of thumb: A well-tuned SQL server should be able to handle 200% of average/peak load. A service that typically gets 500 concurrent connections should be tricked out to handle 1000, at least. That's what stress testing is for.

Your energies are better spent fixing what's broken, not building complicated loops to compensate for deficiencies in another part of the system.

$0.02 granted