mirror of
https://github.com/unraid/webgui.git
synced 2026-04-28 13:59:21 -05:00
Add ETA hysteresis to smooth fluctuations
- Added time_to_seconds() and seconds_to_time() helper functions - Modified calculate_eta() to use hysteresis (70% last rsync ETA, 30% calculated) - Static variable in parse_rsync_progress() stores last known rsync ETA - At 0% progress: use last known ETA if available, otherwise N/A - Prevents ETA from jumping wildly when rsync alternates between ETA and elapsed time - Smooths out rounding errors at low percentages
This commit is contained in:
@@ -61,7 +61,21 @@ function mb_strimhalf($text, $width, $trim_marker = "") {
|
||||
return mb_substr($text, 0, $half) . $trim_marker . mb_substr($text, -1 - $half);
|
||||
}
|
||||
|
||||
function calculate_eta($transferred, $percent, $speed) {
|
||||
function time_to_seconds($time_str) {
|
||||
if (!preg_match('/^(\d+):(\d+):(\d+)$/', $time_str, $matches)) {
|
||||
return null;
|
||||
}
|
||||
return intval($matches[1]) * 3600 + intval($matches[2]) * 60 + intval($matches[3]);
|
||||
}
|
||||
|
||||
function seconds_to_time($seconds) {
|
||||
$hours = intval($seconds / 3600);
|
||||
$minutes = intval(($seconds % 3600) / 60);
|
||||
$secs = $seconds % 60;
|
||||
return sprintf("%d:%02d:%02d", $hours, $minutes, $secs);
|
||||
}
|
||||
|
||||
function calculate_eta($transferred, $percent, $speed, $last_rsync_eta_seconds = null) {
|
||||
// Convert transferred size to bytes
|
||||
$multipliers = ['K' => 1024, 'M' => 1024*1024, 'G' => 1024*1024*1024, 'T' => 1024*1024*1024*1024];
|
||||
$transferred_bytes = floatval($transferred);
|
||||
@@ -71,7 +85,7 @@ function calculate_eta($transferred, $percent, $speed) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Convert speed to bytes/sec
|
||||
$speed_bytes = floatval($speed);
|
||||
if (stripos($speed, 'kB/s') !== false) {
|
||||
@@ -81,25 +95,40 @@ function calculate_eta($transferred, $percent, $speed) {
|
||||
} elseif (stripos($speed, 'GB/s') !== false) {
|
||||
$speed_bytes *= 1024 * 1024 * 1024;
|
||||
}
|
||||
|
||||
|
||||
// Calculate total size from percent
|
||||
$percent_val = intval(str_replace('%', '', $percent));
|
||||
|
||||
// At 0%, we cannot calculate ETA reliably from transferred/percent
|
||||
// but we can use the last known rsync ETA if available
|
||||
if ($percent_val == 0) {
|
||||
if ($last_rsync_eta_seconds !== null && $last_rsync_eta_seconds > 0) {
|
||||
return seconds_to_time($last_rsync_eta_seconds);
|
||||
}
|
||||
return "N/A";
|
||||
}
|
||||
|
||||
if ($percent_val > 0 && $percent_val < 100 && $speed_bytes > 0) {
|
||||
$total_bytes = $transferred_bytes * 100 / $percent_val;
|
||||
$remaining_bytes = $total_bytes - $transferred_bytes;
|
||||
$eta_seconds = intval($remaining_bytes / $speed_bytes);
|
||||
$calculated_eta_seconds = intval($remaining_bytes / $speed_bytes);
|
||||
|
||||
// Format as HH:MM:SS
|
||||
$hours = intval($eta_seconds / 3600);
|
||||
$minutes = intval(($eta_seconds % 3600) / 60);
|
||||
$seconds = $eta_seconds % 60;
|
||||
return sprintf("%d:%02d:%02d", $hours, $minutes, $seconds);
|
||||
// Apply hysteresis: blend with last known rsync ETA to smooth out fluctuations
|
||||
if ($last_rsync_eta_seconds !== null && $last_rsync_eta_seconds > 0) {
|
||||
// Weight: 70% last rsync ETA, 30% calculated ETA
|
||||
$eta_seconds = intval($last_rsync_eta_seconds * 0.7 + $calculated_eta_seconds * 0.3);
|
||||
} else {
|
||||
$eta_seconds = $calculated_eta_seconds;
|
||||
}
|
||||
|
||||
return seconds_to_time($eta_seconds);
|
||||
}
|
||||
|
||||
|
||||
return "N/A";
|
||||
}
|
||||
|
||||
function parse_rsync_progress($status, $action_label) {
|
||||
static $last_rsync_eta_seconds = null;
|
||||
|
||||
// initialize text array with action label
|
||||
$text[0] = $action_label . "... ";
|
||||
@@ -118,14 +147,17 @@ function parse_rsync_progress($status, $action_label) {
|
||||
$percent = $parts[1];
|
||||
$speed = $parts[2];
|
||||
$time = $parts[3];
|
||||
|
||||
|
||||
// Check if this is an ETA line or elapsed time line
|
||||
// ETA lines have only 4 parts, elapsed time lines have additional (xfr#...) info
|
||||
if (isset($parts[4])) {
|
||||
// Calculate our own ETA from transferred size, percent, and speed
|
||||
$time = calculate_eta($transferred, $percent, $speed);
|
||||
// Elapsed time line - calculate our own ETA with hysteresis
|
||||
$time = calculate_eta($transferred, $percent, $speed, $last_rsync_eta_seconds);
|
||||
} else {
|
||||
// ETA line from rsync - store it for hysteresis
|
||||
$last_rsync_eta_seconds = time_to_seconds($time);
|
||||
}
|
||||
|
||||
|
||||
$text[1] = _('Completed') . ": " . $percent . ", " . _('Speed') . ": " . $speed . ", " . _('ETA') . ": " . $time;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user