Example #1
0
 private static function _step_send_pending_files($startAt = 0)
 {
     // Load state into self::$_state & fileoptions object into self::$_stateObj.
     if (false === self::_load_state()) {
         return false;
     }
     if (0 == $startAt) {
         $startAt = self::$_state['stats']['last_filesend_startat'];
         pb_backupbuddy::status('details', 'Starting to send pending files at position `' . $startAt . '` based on stored stats position.');
     } else {
         pb_backupbuddy::status('details', 'Starting to send pending files at position `' . $startAt . '` based on passed value.');
     }
     if (false === self::_load_catalog()) {
         return false;
     }
     require_once pb_backupbuddy::plugin_path() . '/destinations/bootstrap.php';
     // Truncate log if it is getting too large. Keeps newest half.
     self::_truncate_log();
     // Loop through files in the catalog.
     $loopCount = 0;
     $checkCount = 0;
     $sendTimeSum = 0;
     $sendSizeSum = 0;
     $sendAttemptCount = 0;
     $logTruncateCheck = 0;
     $lastSendThisPass = false;
     $sendMoreRemain = false;
     $sendAttemptCount = 0;
     $lackSignatureData = 0;
     $tooManyAttempts = 0;
     foreach (self::$_catalog as $signatureFile => &$signatureDetails) {
         $loopCount++;
         if (0 != $startAt) {
             // Resuming...
             if ($loopCount < $startAt) {
                 continue;
             }
         }
         $checkCount++;
         // Every X files that get sent, make sure log file is not getting too big AND back up catalog.
         if (0 == ($sendAttemptCount + 1) % 150) {
             // Backup catalog.
             self::backup_catalog();
         }
         // If already backed up OR we do not have signature data yet then skip for now.
         if (0 != $signatureDetails['b'] || 0 == $signatureDetails['m']) {
             if (0 == $signatureDetails['m']) {
                 $lackSignatureData++;
             }
             continue;
         }
         // If too many attempts have passed then skip.
         if ($signatureDetails['t'] >= self::MAX_SEND_ATTEMPTS) {
             $tooManyAttempts++;
             continue;
         }
         // Load destination settings.
         $destination_settings = self::get_destination_settings();
         // If too many remote sends have failed today then give up for now since something is likely wrong.
         if (self::$_state['stats']['recent_send_fails'] > $destination_settings['max_daily_failures']) {
             $error = 'Error #5002: Too many file transfer failures have occurred so stopping transfers. We will automatically try again in 12 hours. Verify there are no remote file transfer problems. Check recently send file logs on Remote Destinations page. Don\'t want to wait? Pause Files process then select "Reset Send Attempts" under "Advanced Troubleshooting Options".';
             backupbuddy_core::addNotification('live_error', 'BackupBuddy Stash Live Error', $error);
             self::$_state['step']['last_status'] = $error;
             pb_backupbuddy::status('error', $error);
             return false;
         }
         // If this is not the first file we've sent this pass, see if we have enough time for more.
         if ($sendSizeSum > 0) {
             // Check if it appears we have enough time to send at least a full single chunk in this pass or if we need to pass off to a subsequent run.
             $send_speed = $sendSizeSum / 1048576 / $sendTimeSum;
             // Estimated speed at which we can send files out. Unit: MB / sec.
             $time_elapsed = microtime(true) - pb_backupbuddy::$start_time;
             $time_remaining = $destination_settings['max_time'] - ($time_elapsed + self::TIME_WIGGLE_ROOM);
             // Estimated time remaining before PHP times out. Unit: seconds.
             $size_possible_with_remaining_time = $send_speed * $time_remaining;
             // Size possible to send with remaining time (takes into account wiggle room).
             $size_to_send = $signatureDetails['s'] / 1048576;
             // Size we want to send this pass. Unit: MB.
             if ($destination_settings['max_burst'] < $size_to_send) {
                 // If the chunksize is smaller than the full file then cap at sending that much.
                 $size_to_send = $destination_settings['max_burst'];
             }
             if ($size_possible_with_remaining_time < $size_to_send) {
                 // File (or chunk) is bigger than what we have time to send.
                 $lastSendThisPass = true;
                 $sendMoreRemain = true;
                 $send_speed_status = 'Not enough time to send more. To continue in next live_periodic pass.';
             } else {
                 $send_speed_status = 'Enough time to send more. Preparing for send.';
             }
             pb_backupbuddy::status('details', 'Not the first normal file to send this pass. Send speed: `' . $send_speed . '` MB/sec. Time elapsed: `' . $time_elapsed . '` sec. Time remaining (with wiggle): `' . $time_remaining . '` sec based on reported max time of `' . $destination_settings['max_time'] . '` sec. Size possible with remaining time: `' . $size_possible_with_remaining_time . '` MB. Size to chunk (greater of filesize or chunk): `' . $size_to_send . '` MB. Conclusion: `' . $send_speed_status . '`.');
         }
         // end subsequent send time check.
         // NOT out of time so send this.
         if (true !== $lastSendThisPass) {
             // Run cleanup on send files.
             require_once pb_backupbuddy::plugin_path() . '/classes/housekeeping.php';
             backupbuddy_housekeeping::trim_remote_send_stats($file_prefix = 'send-live_', $limit = $destination_settings['max_send_details_limit'], '', $purge_log = true);
             // Only keep last 5 send fileoptions.
             // Moved into trim_remote_send_stats(). backupbuddy_housekeeping::purge_logs( $file_prefix = 'status-remote_send-live_', $limit = $destination_settings['max_send_details_limit'] ); // Only keep last 5 send logs.
             // Increment try count for transfer attempts and save.
             $signatureDetails['t']++;
             self::$_catalogObj->save();
             // Save position in case process starts over to prevent race conditions resulting in double send of files.
             $destination_settings['_live_next_step'] = array('send_pending_files', array());
             // Next function and args to try and run after finishing send of this file.
             self::$_state['stats']['last_filesend_startat'] = $loopCount + 1;
             self::$_stateObj->save();
             $full_file = ABSPATH . substr($signatureFile, 1);
             if (!file_exists($full_file)) {
                 pb_backupbuddy::status('details', 'File in catalog no longer exists (or permissions block). Skipping send of file `' . $full_file . '`.');
             } else {
                 // Send file. AFTER success sending this Stash2 destination will automatically trigger the live_periodic processing _IF_ multipart send. If success or fail the we come back here to potentially send more files in the same PHP pass so small files don't each need their own PHP page run.  Unless the process has restarted then this will still be the 'next' function to run.
                 $send_id = 'live_' . md5($signatureFile) . '-' . pb_backupbuddy::random_string(6);
                 pb_backupbuddy::status('details', 'Live starting send function.');
                 $sendTimeStart = microtime(true);
                 // Close catalog & state while sending if > X size to prevent collisions.
                 if ($signatureDetails['s'] > self::CLOSE_CATALOG_WHEN_SENDING_FILESIZE) {
                     self::$_catalogObj = '';
                     self::$_stateObj = '';
                 }
                 // Send file to remote.
                 $sendAttemptCount++;
                 $result = pb_backupbuddy_destinations::send($destination_settings, $full_file, $send_id, $delete_after = false, $isRetry = false, $trigger = 'live_periodic', $destination_id = backupbuddy_live::getLiveID());
                 // Re-open catalog (if closed).
                 if (false === self::_load_state()) {
                     pb_backupbuddy::status('error', 'Error #5489458443: Unable to re-open temporarily closed state.');
                     return false;
                 }
                 if (false === self::_load_catalog()) {
                     pb_backupbuddy::status('error', 'Error #5489458443: Unable to re-open temporarily closed catalog.');
                     return false;
                 }
                 $sendTimeFinish = microtime(true);
                 if (true === $result) {
                     $result_status = 'Success sending in single pass.';
                     $sendTimeSum += $sendTimeFinish - $sendTimeStart;
                     // Add to time sent sending.
                     // Set a minimum threshold so small files don't make server appear slower than reality due to overhead.
                     $minimum_size_threshold = self::MINIMUM_SIZE_THRESHOLD_FOR_SPEED_CALC;
                     // Pretend file is at least 500k each.
                     if ($signatureDetails['s'] < $minimum_size_threshold) {
                         $sendSizeSum += $minimum_size_threshold;
                     } else {
                         $sendSizeSum += $signatureDetails['s'];
                         // Add to size of data sent.
                     }
                 } elseif (false === $result) {
                     self::$_state['stats']['recent_send_fails']++;
                     $result_status = 'Failure sending in single/first pass. See log above for error details. Failed sends today: `' . self::$_state['stats']['recent_send_fails'] . '`.';
                 } elseif (is_array($result)) {
                     $result_status = 'Chunking commenced. Ending sends for this pass.';
                     //$lastSendThisPass = true;
                     // TODO: Ideally at this point we would have Live sleep until the large chunked file finished sending.
                 }
                 pb_backupbuddy::status('details', 'Live ended send files function. Status: ' . $result_status . '.');
             }
             // end file exists.
         }
         // Check if we are done sending for this PHP pass/run.
         if (true === $lastSendThisPass) {
             break;
         }
     }
     // End foreach signatures.
     pb_backupbuddy::status('details', 'Checked `' . $checkCount . '` items for sending. Sent `' . $sendAttemptCount . '`. Skipped due to too many send attempts: `' . $tooManyAttempts . '`. Skipped due to lacking signature data: `' . $lackSignatureData . '`.');
     if ($tooManyAttempts > 0) {
         $warning = 'Warning #5003. `' . $tooManyAttempts . '` files were skipped due to too many send attempts failing. Check the Remote Destinations page\'s Recently sent files list to check for errors of failed sends. To manually reset sends Pause the Files process and wait for it to finish, then select the Advanced Troubleshooting Option to "Reset Send Attempts".';
         pb_backupbuddy::status('warning', $warning);
         backupbuddy_core::addNotification('live_error', 'BackupBuddy Stash Live Error', $warning);
     }
     // Schedule next run if we still have more files to potentially send.
     if (true === $sendMoreRemain) {
         return array('Sending queued files', array($loopCount));
     } else {
         // No more files.
         self::$_state['stats']['last_filesend_startat'] = 0;
         // Reset the startat location.
         pb_backupbuddy::status('details', 'No more files remain. Reset filesend startat position back to 0.');
         return true;
     }
 }
				success: function(data){
					data = jQuery.trim( data );
					if ( '1' == data ) {
						alert( 'Remote transfer aborted. This may take a moment to take effect.' );
					} else {
						alert( 'Error #85448949. Unexpected server response. Details: `' + data + '`.' );
					}
				}
			});
			return false;
		});
	});
</script>
<?php 
require_once pb_backupbuddy::plugin_path() . '/classes/housekeeping.php';
backupbuddy_housekeeping::trim_remote_send_stats();
$remote_sends = array();
$send_fileoptions = pb_backupbuddy::$filesystem->glob_by_date(backupbuddy_core::getLogDirectory() . 'fileoptions/send-*.txt');
if (!is_array($send_fileoptions)) {
    $send_fileoptions = array();
}
foreach ($send_fileoptions as $send_fileoption) {
    $send_id = str_replace('.txt', '', str_replace('send-', '', basename($send_fileoption)));
    pb_backupbuddy::status('details', 'About to load fileoptions data.');
    require_once pb_backupbuddy::plugin_path() . '/classes/fileoptions.php';
    pb_backupbuddy::status('details', 'Fileoptions instance #23.');
    $fileoptions_obj = new pb_backupbuddy_fileoptions(backupbuddy_core::getLogDirectory() . 'fileoptions/send-' . $send_id . '.txt', $read_only = true, $ignore_lock = true, $create_file = false);
    if (true !== ($result = $fileoptions_obj->is_ok())) {
        pb_backupbuddy::status('error', __('Fatal Error #9034.32393. Unable to access fileoptions data.', 'it-l10n-backupbuddy') . ' Error: ' . $result);
        return false;
    }