3

I have a WordPress plugin with a backup script that executes on a schedule. The catch is, if someone hits the page multiple times in succession it can execute the backup script multiple times. Any thoughts on how to prevent multiple executions?

global $bwpsoptions;

        if ( get_transient( 'bit51_bwps_backup' ) === false ) {

            set_transient( 'bit51_bwps_backup', '1', 300 );

            if ( $bwpsoptions['backup_enabled'] == 1 ) {

                $nextbackup = $bwpsoptions['backup_next']; //get next schedule
                $lastbackup = $bwpsoptions['backup_last']; //get last backup

                switch ( $bwpsoptions['backup_interval'] ) { //schedule backup at appropriate time
                    case '0':
                        $next = 60 * 60 * $bwpsoptions['backup_time'];
                        break;
                    case '1':
                        $next = 60 * 60 * 24 * $bwpsoptions['backup_time'];
                        break;
                    case '2':
                        $next = 60 * 60 * 24 * 7  * $bwpsoptions['backup_time'];
                        break;
                }

                if ( ( $lastbackup == '' || $nextbackup < time() ) && get_transient( 'bit51_bwps_backup' ) === false ) {

                    $bwpsoptions['backup_last'] = time();

                    if ( $lastbackup == '' ) {

                        $bwpsoptions['backup_next'] = ( time() + $next );

                    } else {

                        $bwpsoptions['backup_next'] = ( $lastbackup + $next );

                    }


                    update_option( $this->primarysettings, $bwpsoptions );

                    $this->execute_backup(); //execute backup

                }

            }

        }
Chris Wiegman
  • 382
  • 1
  • 2
  • 10
  • 3
    Set a field in a database indicating the time, and calculate it so that if the difference between the last time the script is run and the current time is greater than `t`, don't run the script. – Madara's Ghost Mar 18 '12 at 18:05
  • Where are you populating `$bwpsoptions`? If it is not from an external source, like database, file, session etc, then it will be forgotten on the next page load. – d_inevitable Mar 18 '12 at 18:08

4 Answers4

3
  • Create a file at the start of the code.
  • When the code finishes running delete the file.
  • At the beginning of the code make sure thefile doesn't exist before running.

Sort of like the apt-get lock in linux.

mr.user1065741
  • 652
  • 3
  • 9
  • 19
3

If your site is very busy and basic locking mechanism arn't working (I personally can't imagine that but oh well!), you can try the solution from PHP session's garbage collector.

Just randomly choose a number between 0 and 10 and if the number is 0, do the backup. If now 10 user's call your backup script at nearly the same time, statistically only one will actually execute the backup.

define("BACKUP_PROBABILITY", 10);
if (mt_rand(0, BACKUP_PROBABILITY) == 0)
    doBackup();

You can increase the maximum (the 10) if your site is very highly frequented.

If in those 10 visits none got the 0, the next 10 visitors will get their chance.

You will need of course some kind of locking mechanism and it is still possible (though unplausible) that you will end up with more than one or even 10 backups.

I found this question about mutexes (locks) in PHP. Might be helpful: PHP mutual exclusion (mutex)

Community
  • 1
  • 1
Basti
  • 3,998
  • 1
  • 18
  • 21
1

Store the last backup date/time in some external file on server or into database, and use a check against that value!

hjpotter92
  • 78,589
  • 36
  • 144
  • 183
  • Why not have this backup script on a separate page? and just call to start/include the page when the condition is satisfied! – hjpotter92 Mar 18 '12 at 18:12
  • 1
    @ChrisWiegman, the **A** was "external file on server or *into database*". You won't have this problem if you use a batchQ row/table in your D/B. Just update the time on the backup timestamp row where the time=requested_time. If affected rows for this update execution == 1 then this process does the backup otherwise some other process beat it to it. – TerryE Mar 18 '12 at 18:43
0

I assume that this backup thing makes a backup somewhere.

So check the metadata on the latest backup, and if it's creation time is not far enough in the past, don't do the backup.

I assume there's a good reason why this isn't a cron job?

zebediah49
  • 7,467
  • 1
  • 33
  • 50
  • Yeah, it's not a cron job because too many folks just can't handle it. I have to use this in an environment where an actual cron job is not available and wp-cron isn't flexible enough. – Chris Wiegman Mar 18 '12 at 18:12