Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Retry a try/catch when it fails

Tags:

php

I've tried a few different try/catch loops to try and solve problems automatically but they always seem to cause the software to die.

$doLoop = true;

while ($doLoop) {

    try {
        //do a thing
        insertIntoDb($data);
    } catch (Exception $e) {
        //try again
        insertIntoDb($data);
        //write error to file
        writeError($e);
    }
}

Here's my original try/catch.

The issue is sometimes the MySQL server 'goes away' and I need to catch that exception and keep retrying until it comes back.

What can I change here to get this to keep retrying until successful?

like image 362
Chris R. Avatar asked Jan 30 '15 15:01

Chris R.


2 Answers

use a break as last statement in your try block to leave the loop only on success:

while (true) {
    try {
        // do something
        insertIntoDb($data);
        break;
    } 
    catch (Exception $e) {
        writeError($e);
    }
    // sleep 200ms to give the MySQL server time to come back up
    usleep(200000);
}

But you should also limit the number of retries by using a for loop instead.
Otherwise, your code might run in an infinite loop:

// limit the number of retries
for ($i=1; $i <= 3; $i++) {
    try {
        // do something
        insertIntoDb($data);
        break;
    } 
    catch (Exception $e) {
        writeError($e);
    }
    // sleep 200ms to give the MySQL server time to come back up
    usleep(200000);
}

Also note the usleep() call:

This is important because otherwise the PHP process would take all resources (100% CPU) while retrying as fast as possible. You can adjust the value to fit your needs. (maybe 200ms is too long or too short in your case)

Also note that you may need to reconnect to the MySQL DB on failure! I did not include code for that case in my example.

like image 125
Kaii Avatar answered Oct 17 '22 21:10

Kaii


This will only work, if your function insertIntoDb will throw an Exception. If you use mysql* functions, then it won't work.

After insertIntoDb($data); you should set $doLoop = false

like image 2
PKeidel Avatar answered Oct 17 '22 21:10

PKeidel