mirror of
https://github.com/Terranom674/Piwigo_Bratonien_Tools.git
synced 2026-09-19 19:54:31 +00:00
Compare commits
11 Commits
ceea3b5483
...
86a2a0fbec
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
86a2a0fbec | ||
|
|
c058e48fb0 | ||
|
|
d20be6a39a | ||
|
|
3d7114d782 | ||
|
|
c20795d108 | ||
|
|
2863a51acf | ||
|
|
ec8036d226 | ||
|
|
0094942f68 | ||
|
|
12834041be | ||
|
|
1f2651b8f0 | ||
|
|
791d67929b |
@@ -32,7 +32,7 @@ function bratonien_tools_get_tools()
|
|||||||
return array(
|
return array(
|
||||||
'image_cache_clear' => array('handler' => 'bratonien_tools_clear_image_cache_atomic'),
|
'image_cache_clear' => array('handler' => 'bratonien_tools_clear_image_cache_atomic'),
|
||||||
'image_cache_build' => array('handler' => 'bratonien_tools_start_combined_image_cache_build'),
|
'image_cache_build' => array('handler' => 'bratonien_tools_start_combined_image_cache_build'),
|
||||||
'image_cache_cancel' => array('handler' => 'bratonien_tools_cancel_main_cache_build'),
|
'image_cache_cancel' => array('handler' => 'bratonien_tools_cancel_combined_image_cache_build'),
|
||||||
'image_cache_worker_settings' => array('handler' => 'bratonien_tools_save_cache_worker_settings'),
|
'image_cache_worker_settings' => array('handler' => 'bratonien_tools_save_cache_worker_settings'),
|
||||||
'image_cache_webdav_warmup_settings' => array('handler' => 'bratonien_tools_save_webdav_warmup_settings'),
|
'image_cache_webdav_warmup_settings' => array('handler' => 'bratonien_tools_save_webdav_warmup_settings'),
|
||||||
'image_cache_webdav_warmup_manual' => array('handler' => 'bratonien_tools_start_webdav_warmup_manual'),
|
'image_cache_webdav_warmup_manual' => array('handler' => 'bratonien_tools_start_webdav_warmup_manual'),
|
||||||
|
|||||||
@@ -57,6 +57,11 @@ function bratonien_tools_webdav_warmup_status_file_for_connection($connection_id
|
|||||||
return PHPWG_ROOT_PATH.PWG_LOCAL_DIR.'bratonien-webdav-warmup.status-'.(int)$connection_id.'.json';
|
return PHPWG_ROOT_PATH.PWG_LOCAL_DIR.'bratonien-webdav-warmup.status-'.(int)$connection_id.'.json';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function bratonien_tools_webdav_warmup_cancel_file_for_connection($connection_id)
|
||||||
|
{
|
||||||
|
return PHPWG_ROOT_PATH.PWG_LOCAL_DIR.'bratonien-webdav-warmup.cancel-'.(int)$connection_id;
|
||||||
|
}
|
||||||
|
|
||||||
function bratonien_tools_webdav_warmup_write_status($connection_id, $state, $message, array $extra=array())
|
function bratonien_tools_webdav_warmup_write_status($connection_id, $state, $message, array $extra=array())
|
||||||
{
|
{
|
||||||
$file = bratonien_tools_webdav_warmup_status_file_for_connection($connection_id);
|
$file = bratonien_tools_webdav_warmup_status_file_for_connection($connection_id);
|
||||||
@@ -180,6 +185,10 @@ function bratonien_tools_start_webdav_warmup_mode($mode, $message)
|
|||||||
$run_id = date('YmdHis').'-'.bin2hex(random_bytes(4));
|
$run_id = date('YmdHis').'-'.bin2hex(random_bytes(4));
|
||||||
foreach ($connections as $connection_id=>$runtime)
|
foreach ($connections as $connection_id=>$runtime)
|
||||||
{
|
{
|
||||||
|
// Ein altes Abbruchsignal darf niemals den nächsten bewusst gestarteten
|
||||||
|
// Lauf stoppen. Es wird unmittelbar vor dem neuen Start entfernt.
|
||||||
|
@unlink(bratonien_tools_webdav_warmup_cancel_file_for_connection($connection_id));
|
||||||
|
|
||||||
bratonien_tools_webdav_warmup_write_status(
|
bratonien_tools_webdav_warmup_write_status(
|
||||||
$connection_id,
|
$connection_id,
|
||||||
'queued',
|
'queued',
|
||||||
@@ -224,6 +233,72 @@ function bratonien_tools_start_webdav_cache_rebuild()
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function bratonien_tools_request_webdav_cache_cancel()
|
||||||
|
{
|
||||||
|
$requested = 0;
|
||||||
|
foreach (bratonien_tools_webdav_warmup_connections() as $connection_id=>$runtime)
|
||||||
|
{
|
||||||
|
$status_file = bratonien_tools_webdav_warmup_status_file_for_connection($connection_id);
|
||||||
|
$status = null;
|
||||||
|
if (is_file($status_file) && is_readable($status_file))
|
||||||
|
{
|
||||||
|
$raw = @file_get_contents($status_file);
|
||||||
|
$status = $raw !== false ? json_decode($raw, true) : null;
|
||||||
|
}
|
||||||
|
if (!is_array($status)) $status = array();
|
||||||
|
$state = (string)($status['state'] ?? 'idle');
|
||||||
|
if (!in_array($state, array('queued','scan','running','cancelling'), true)) continue;
|
||||||
|
|
||||||
|
$cancel = bratonien_tools_webdav_warmup_cancel_file_for_connection($connection_id);
|
||||||
|
if (@file_put_contents($cancel, (string)time()."\n", LOCK_EX) === false)
|
||||||
|
{
|
||||||
|
throw new RuntimeException('WebDAV-Abbruchsignal für Verbindung #'.(int)$connection_id.' konnte nicht geschrieben werden.');
|
||||||
|
}
|
||||||
|
@chmod($cancel, 0664);
|
||||||
|
|
||||||
|
$extra = $status;
|
||||||
|
unset($extra['state'], $extra['message'], $extra['connection_id'], $extra['updated_at']);
|
||||||
|
$extra['cancel_requested'] = true;
|
||||||
|
bratonien_tools_webdav_warmup_write_status(
|
||||||
|
$connection_id,
|
||||||
|
'cancelling',
|
||||||
|
'Abbruch angefordert. Der aktuell laufende Batch wird noch vollständig beendet; danach werden keine weiteren Nextcloud-Originale geladen.',
|
||||||
|
$extra
|
||||||
|
);
|
||||||
|
$requested++;
|
||||||
|
}
|
||||||
|
return $requested;
|
||||||
|
}
|
||||||
|
|
||||||
|
function bratonien_tools_cancel_combined_image_cache_build()
|
||||||
|
{
|
||||||
|
$webdav = bratonien_tools_request_webdav_cache_cancel();
|
||||||
|
$local = false;
|
||||||
|
if (function_exists('bratonien_tools_main_cache_process_active') && function_exists('bratonien_tools_main_cache_is_running'))
|
||||||
|
{
|
||||||
|
$local = bratonien_tools_main_cache_process_active() || bratonien_tools_main_cache_is_running();
|
||||||
|
}
|
||||||
|
if ($local && function_exists('bratonien_tools_request_main_cache_cancel'))
|
||||||
|
{
|
||||||
|
bratonien_tools_request_main_cache_cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($webdav > 0 && $local)
|
||||||
|
{
|
||||||
|
return array('message'=>'Cache-Abbruch angefordert. Der aktuelle WebDAV-Batch wird noch beendet; lokale Cache-Worker erhalten ebenfalls sofort das Abbruchsignal.');
|
||||||
|
}
|
||||||
|
if ($webdav > 0)
|
||||||
|
{
|
||||||
|
return array('message'=>'WebDAV-Cache-Abbruch angefordert. Der aktuell laufende Batch wird noch vollständig beendet; danach ist Schluss.');
|
||||||
|
}
|
||||||
|
if ($local)
|
||||||
|
{
|
||||||
|
return array('message'=>'Lokaler Piwigo-Cache-Abbruch wurde angefordert.');
|
||||||
|
}
|
||||||
|
|
||||||
|
return array('message'=>'Es läuft aktuell kein Cache-Aufbau.');
|
||||||
|
}
|
||||||
|
|
||||||
function bratonien_tools_has_local_cache_sources()
|
function bratonien_tools_has_local_cache_sources()
|
||||||
{
|
{
|
||||||
if (!function_exists('bratonien_tools_webdav_materialize_source_info')) return true;
|
if (!function_exists('bratonien_tools_webdav_materialize_source_info')) return true;
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ function bratonien_tools_status_webdav_label(array $status)
|
|||||||
$state = (string)($status['state'] ?? 'idle');
|
$state = (string)($status['state'] ?? 'idle');
|
||||||
$prefix = $connection > 0 ? 'WebDAV #'.$connection.': ' : 'WebDAV: ';
|
$prefix = $connection > 0 ? 'WebDAV #'.$connection.': ' : 'WebDAV: ';
|
||||||
|
|
||||||
if ($state === 'queued') return $prefix.((string)($status['message'] ?? '') !== '' ? (string)$status['message'] : 'Worker wartet auf den Start.');
|
if ($state === 'queued' || $state === 'waiting') return $prefix.((string)($status['message'] ?? '') !== '' ? (string)$status['message'] : 'Worker wartet auf den nächsten sicheren Startpunkt.');
|
||||||
if ($state === 'scan')
|
if ($state === 'scan')
|
||||||
{
|
{
|
||||||
$sources = (int)($status['shadow_sources'] ?? 0);
|
$sources = (int)($status['shadow_sources'] ?? 0);
|
||||||
@@ -64,6 +64,9 @@ function bratonien_tools_status_webdav_label(array $status)
|
|||||||
if ($total > 0) $parts[] = $completed.' / '.$total.' Quellen dieser Stufe abgeschlossen';
|
if ($total > 0) $parts[] = $completed.' / '.$total.' Quellen dieser Stufe abgeschlossen';
|
||||||
return implode(' · ', $parts).'.';
|
return implode(' · ', $parts).'.';
|
||||||
}
|
}
|
||||||
|
if ($state === 'cancelling') return $prefix.((string)($status['message'] ?? '') !== '' ? (string)$status['message'] : 'Abbruch angefordert; aktueller Batch wird noch beendet.');
|
||||||
|
if ($state === 'cancelled') return $prefix.((string)($status['message'] ?? '') !== '' ? (string)$status['message'] : 'Cache-Aufbau wurde abgebrochen.');
|
||||||
|
if ($state === 'partial') return $prefix.((string)($status['message'] ?? '') !== '' ? (string)$status['message'] : 'Einzelne Quellen sind noch offen und werden beim nächsten Lauf erneut versucht.');
|
||||||
if ($state === 'preempted') return $prefix.'Stufe 2 wurde nach einem vollständigen Batch unterbrochen, damit neue Connector-Inhalte zuerst verarbeitet werden können.';
|
if ($state === 'preempted') return $prefix.'Stufe 2 wurde nach einem vollständigen Batch unterbrochen, damit neue Connector-Inhalte zuerst verarbeitet werden können.';
|
||||||
if ($state === 'complete') return $prefix.((string)($status['message'] ?? '') !== '' ? (string)$status['message'] : 'Verarbeitung abgeschlossen.');
|
if ($state === 'complete') return $prefix.((string)($status['message'] ?? '') !== '' ? (string)$status['message'] : 'Verarbeitung abgeschlossen.');
|
||||||
if ($state === 'error' || $state === 'fatal') return $prefix.'FEHLER: '.((string)($status['message'] ?? '') !== '' ? (string)$status['message'] : 'WebDAV-Verarbeitung fehlgeschlagen.');
|
if ($state === 'error' || $state === 'fatal') return $prefix.'FEHLER: '.((string)($status['message'] ?? '') !== '' ? (string)$status['message'] : 'WebDAV-Verarbeitung fehlgeschlagen.');
|
||||||
@@ -93,6 +96,10 @@ usort($webdav, function($a, $b) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
$webdav_active = false;
|
$webdav_active = false;
|
||||||
|
$webdav_waiting = false;
|
||||||
|
$webdav_partial = false;
|
||||||
|
$webdav_cancelling = false;
|
||||||
|
$webdav_cancelled = false;
|
||||||
$webdav_error = false;
|
$webdav_error = false;
|
||||||
$webdav_pending = false;
|
$webdav_pending = false;
|
||||||
$webdav_latest = 0;
|
$webdav_latest = 0;
|
||||||
@@ -120,16 +127,16 @@ foreach ($webdav as &$status)
|
|||||||
$webdav_source_total += $selected;
|
$webdav_source_total += $selected;
|
||||||
$webdav_progress_total += $selected * 2;
|
$webdav_progress_total += $selected * 2;
|
||||||
}
|
}
|
||||||
elseif ($state === 'running')
|
elseif ($state === 'running' || $state === 'cancelling')
|
||||||
{
|
{
|
||||||
$selected = max(0, (int)($status['selected_total'] ?? 0));
|
$selected = max(0, (int)($status['selected_total'] ?? $status['selected'] ?? 0));
|
||||||
$stage = max(1, (int)($status['stage'] ?? 1));
|
$stage = max(1, (int)($status['stage'] ?? 1));
|
||||||
$stage_completed = max(0, min($selected, (int)($status['stage_completed'] ?? 0)));
|
$stage_completed = max(0, min($selected, (int)($status['stage_completed'] ?? 0)));
|
||||||
$webdav_source_total += $selected;
|
$webdav_source_total += $selected;
|
||||||
$webdav_progress_total += $selected * 2;
|
$webdav_progress_total += $selected * 2;
|
||||||
$webdav_progress_completed += $stage >= 2 ? $selected + $stage_completed : $stage_completed;
|
$webdav_progress_completed += $stage >= 2 ? $selected + $stage_completed : $stage_completed;
|
||||||
}
|
}
|
||||||
elseif ($state === 'complete' || $state === 'error' || $state === 'fatal' || $state === 'preempted')
|
elseif (in_array($state, array('complete','error','fatal','preempted','cancelled','waiting','partial'), true))
|
||||||
{
|
{
|
||||||
$selected = max(0, (int)($status['selected'] ?? 0));
|
$selected = max(0, (int)($status['selected'] ?? 0));
|
||||||
if ($selected > 0)
|
if ($selected > 0)
|
||||||
@@ -138,13 +145,19 @@ foreach ($webdav as &$status)
|
|||||||
$stage2_completed = max(0, (int)($status['stage2_completed'] ?? 0));
|
$stage2_completed = max(0, (int)($status['stage2_completed'] ?? 0));
|
||||||
$stage1_failed = max(0, (int)($status['stage1_failed'] ?? 0));
|
$stage1_failed = max(0, (int)($status['stage1_failed'] ?? 0));
|
||||||
$stage2_failed = max(0, (int)($status['stage2_failed'] ?? 0));
|
$stage2_failed = max(0, (int)($status['stage2_failed'] ?? 0));
|
||||||
|
$stage1_deferred = max(0, (int)($status['stage1_deferred'] ?? 0));
|
||||||
|
$stage2_deferred = max(0, (int)($status['stage2_deferred'] ?? 0));
|
||||||
$webdav_source_total += $selected;
|
$webdav_source_total += $selected;
|
||||||
$webdav_progress_total += $selected * 2;
|
$webdav_progress_total += $selected * 2;
|
||||||
$webdav_progress_completed += min($selected * 2, $stage1_completed + $stage2_completed + $stage1_failed + $stage2_failed);
|
$webdav_progress_completed += min($selected * 2, $stage1_completed + $stage2_completed + $stage1_failed + $stage2_failed + $stage1_deferred + $stage2_deferred);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (in_array($state, array('queued','scan','running'), true)) $webdav_active = true;
|
if (in_array($state, array('queued','scan','running'), true)) $webdav_active = true;
|
||||||
|
if ($state === 'waiting') $webdav_waiting = true;
|
||||||
|
if ($state === 'partial') $webdav_partial = true;
|
||||||
|
if ($state === 'cancelling') $webdav_cancelling = true;
|
||||||
|
if ($state === 'cancelled') $webdav_cancelled = true;
|
||||||
if ($state === 'preempted') $webdav_pending = true;
|
if ($state === 'preempted') $webdav_pending = true;
|
||||||
if (in_array($state, array('error','fatal'), true)) $webdav_error = true;
|
if (in_array($state, array('error','fatal'), true)) $webdav_error = true;
|
||||||
if ($state !== 'complete') $webdav_all_complete = false;
|
if ($state !== 'complete') $webdav_all_complete = false;
|
||||||
@@ -155,7 +168,7 @@ unset($status);
|
|||||||
$local_state = (string)($local['state'] ?? 'idle');
|
$local_state = (string)($local['state'] ?? 'idle');
|
||||||
$local_updated = (int)($local['updated_at'] ?? 0);
|
$local_updated = (int)($local['updated_at'] ?? 0);
|
||||||
$local_stale = in_array($local_state, array('running','queued'), true) && $local_updated > 0 && (time() - $local_updated) > 45;
|
$local_stale = in_array($local_state, array('running','queued'), true) && $local_updated > 0 && (time() - $local_updated) > 45;
|
||||||
if ($local_stale && !$webdav_active)
|
if ($local_stale && !$webdav_active && !$webdav_cancelling && !$webdav_waiting)
|
||||||
{
|
{
|
||||||
$local['state'] = 'error';
|
$local['state'] = 'error';
|
||||||
$local['message'] = 'Der lokale Piwigo-Teil liefert seit mehr als 45 Sekunden keinen Fortschritt.';
|
$local['message'] = 'Der lokale Piwigo-Teil liefert seit mehr als 45 Sekunden keinen Fortschritt.';
|
||||||
@@ -180,7 +193,15 @@ $local_completed = max(0, min($local_total, (int)($local['completed'] ?? 0)));
|
|||||||
$combined_total = $local_total + $webdav_progress_total;
|
$combined_total = $local_total + $webdav_progress_total;
|
||||||
$combined_completed = $local_completed + min($webdav_progress_total, $webdav_progress_completed);
|
$combined_completed = $local_completed + min($webdav_progress_total, $webdav_progress_completed);
|
||||||
|
|
||||||
if ($webdav_active)
|
if ($webdav_cancelling || $local_state === 'cancelling')
|
||||||
|
{
|
||||||
|
$overall['state'] = 'cancelling';
|
||||||
|
$overall['total'] = $combined_total;
|
||||||
|
$overall['completed'] = $combined_completed;
|
||||||
|
$overall['message'] = 'Cache-Aufbau wird nach dem aktuell laufenden Batch beendet'.($webdav_source_total > 0 ? ' · '.$webdav_source_total.' WebDAV-Quellen' : '').'.';
|
||||||
|
$overall['current'] = implode(' ', $webdav_lines);
|
||||||
|
}
|
||||||
|
elseif ($webdav_active)
|
||||||
{
|
{
|
||||||
$overall['state'] = 'running';
|
$overall['state'] = 'running';
|
||||||
$overall['total'] = $combined_total;
|
$overall['total'] = $combined_total;
|
||||||
@@ -191,6 +212,23 @@ if ($webdav_active)
|
|||||||
$overall['message'] = 'Gesamtaufbau läuft'.($webdav_source_total > 0 ? ' · '.$webdav_source_total.' WebDAV-Quellen' : '').'. '.$local_label;
|
$overall['message'] = 'Gesamtaufbau läuft'.($webdav_source_total > 0 ? ' · '.$webdav_source_total.' WebDAV-Quellen' : '').'. '.$local_label;
|
||||||
$overall['current'] = implode(' ', $webdav_lines);
|
$overall['current'] = implode(' ', $webdav_lines);
|
||||||
}
|
}
|
||||||
|
elseif ($webdav_waiting)
|
||||||
|
{
|
||||||
|
$overall['state'] = 'queued';
|
||||||
|
$overall['total'] = $combined_total;
|
||||||
|
$overall['completed'] = $combined_completed;
|
||||||
|
$overall['message'] = 'Cache-Aufbau pausiert für laufende Connector-Synchronisierung'.($webdav_source_total > 0 ? ' · '.$webdav_source_total.' WebDAV-Quellen' : '').'. Der Indexstand bleibt erhalten.';
|
||||||
|
$overall['current'] = implode(' ', $webdav_lines);
|
||||||
|
}
|
||||||
|
elseif ($webdav_partial)
|
||||||
|
{
|
||||||
|
$overall['state'] = 'queued';
|
||||||
|
$overall['total'] = $combined_total;
|
||||||
|
$overall['completed'] = $combined_completed;
|
||||||
|
$overall['errors'] = 0;
|
||||||
|
$overall['message'] = 'Cache-Aufbau bleibt fortsetzbar: einzelne Quellen sind noch offen; der restliche Bestand wurde weiterverarbeitet.';
|
||||||
|
$overall['current'] = implode(' ', $webdav_lines);
|
||||||
|
}
|
||||||
elseif ($webdav_error || $local_state === 'error')
|
elseif ($webdav_error || $local_state === 'error')
|
||||||
{
|
{
|
||||||
$overall['state'] = 'error';
|
$overall['state'] = 'error';
|
||||||
@@ -211,6 +249,14 @@ elseif ($webdav_pending)
|
|||||||
$overall['message'] = 'Cache-Aufbau wartet auf priorisierte Connector-Inhalte'.($webdav_source_total > 0 ? ' · '.$webdav_source_total.' WebDAV-Quellen' : '').'. '.$local_label;
|
$overall['message'] = 'Cache-Aufbau wartet auf priorisierte Connector-Inhalte'.($webdav_source_total > 0 ? ' · '.$webdav_source_total.' WebDAV-Quellen' : '').'. '.$local_label;
|
||||||
$overall['current'] = implode(' ', $webdav_lines);
|
$overall['current'] = implode(' ', $webdav_lines);
|
||||||
}
|
}
|
||||||
|
elseif ($webdav_cancelled || $local_state === 'cancelled')
|
||||||
|
{
|
||||||
|
$overall['state'] = 'cancelled';
|
||||||
|
$overall['total'] = $combined_total;
|
||||||
|
$overall['completed'] = $combined_completed;
|
||||||
|
$overall['message'] = 'Cache-Aufbau wurde nach dem letzten vollständig abgeschlossenen Batch beendet.';
|
||||||
|
$overall['current'] = implode(' ', $webdav_lines);
|
||||||
|
}
|
||||||
elseif ($webdav_all_complete && $local_state === 'complete')
|
elseif ($webdav_all_complete && $local_state === 'complete')
|
||||||
{
|
{
|
||||||
$overall['state'] = 'complete';
|
$overall['state'] = 'complete';
|
||||||
@@ -224,9 +270,6 @@ elseif ($webdav_all_complete && $local_state === 'complete')
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Ein alter complete-Status darf niemals einen neuen Lauf als fertig markieren.
|
|
||||||
// Idle/unklare WebDAV-Zustände bleiben sichtbar, bis ein echter Lauf einen
|
|
||||||
// aktuellen queued/scan/running/complete/error-Zustand geschrieben hat.
|
|
||||||
$overall['state'] = $local_state === 'complete' ? 'idle' : $local_state;
|
$overall['state'] = $local_state === 'complete' ? 'idle' : $local_state;
|
||||||
$overall['message'] = $local_label;
|
$overall['message'] = $local_label;
|
||||||
if ($webdav_lines) $overall['current'] = implode(' ', $webdav_lines);
|
if ($webdav_lines) $overall['current'] = implode(' ', $webdav_lines);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
/*
|
/*
|
||||||
Plugin Name: Bratonien Tools
|
Plugin Name: Bratonien Tools
|
||||||
Version: 0.9.7.1.27
|
Version: 0.9.7.1.30
|
||||||
Description: Erweiterbare Administrationswerkzeuge fuer die Bratonien-Piwigo-Installation.
|
Description: Erweiterbare Administrationswerkzeuge fuer die Bratonien-Piwigo-Installation.
|
||||||
Plugin URI: https://github.com/Terranom674/Piwigo_Bratonien_Tools
|
Plugin URI: https://github.com/Terranom674/Piwigo_Bratonien_Tools
|
||||||
Author: Bratonien
|
Author: Bratonien
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ $_SERVER['REQUEST_URI'] = '/';
|
|||||||
$_SERVER['SCRIPT_NAME'] = '/plugins/bratonien_tools/runtime/lib/webdav-cache-warmup.php';
|
$_SERVER['SCRIPT_NAME'] = '/plugins/bratonien_tools/runtime/lib/webdav-cache-warmup.php';
|
||||||
$_SERVER['PHP_SELF'] = $_SERVER['SCRIPT_NAME'];
|
$_SERVER['PHP_SELF'] = $_SERVER['SCRIPT_NAME'];
|
||||||
$_SERVER['QUERY_STRING'] = '';
|
$_SERVER['QUERY_STRING'] = '';
|
||||||
$_SERVER['HTTP_USER_AGENT'] = 'Bratonien-WebDAV-Cache-Worker/0.9.7.1.17';
|
$_SERVER['HTTP_USER_AGENT'] = 'Bratonien-WebDAV-Cache-Worker/0.9.7.1.30';
|
||||||
$_SERVER['HTTPS'] = 'off';
|
$_SERVER['HTTPS'] = 'off';
|
||||||
|
|
||||||
require_once(PHPWG_ROOT_PATH.'include/common.inc.php');
|
require_once(PHPWG_ROOT_PATH.'include/common.inc.php');
|
||||||
@@ -54,6 +54,16 @@ function bratonien_tools_cache_warmup_status_file($connection_id)
|
|||||||
return PHPWG_ROOT_PATH.PWG_LOCAL_DIR.'bratonien-webdav-warmup.status-'.(int)$connection_id.'.json';
|
return PHPWG_ROOT_PATH.PWG_LOCAL_DIR.'bratonien-webdav-warmup.status-'.(int)$connection_id.'.json';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function bratonien_tools_cache_warmup_cancel_file($connection_id)
|
||||||
|
{
|
||||||
|
return PHPWG_ROOT_PATH.PWG_LOCAL_DIR.'bratonien-webdav-warmup.cancel-'.(int)$connection_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
function bratonien_tools_cache_warmup_cancel_pending($connection_id)
|
||||||
|
{
|
||||||
|
return is_file(bratonien_tools_cache_warmup_cancel_file($connection_id));
|
||||||
|
}
|
||||||
|
|
||||||
function bratonien_tools_cache_warmup_priority_file($state_dir)
|
function bratonien_tools_cache_warmup_priority_file($state_dir)
|
||||||
{
|
{
|
||||||
return rtrim((string)$state_dir, '/').'/webdav-cache-warmup-priority-sync';
|
return rtrim((string)$state_dir, '/').'/webdav-cache-warmup-priority-sync';
|
||||||
@@ -247,7 +257,7 @@ function bratonien_tools_cache_warmup_download(array $source, array $credentials
|
|||||||
CURLOPT_RETURNTRANSFER=>false,
|
CURLOPT_RETURNTRANSFER=>false,
|
||||||
CURLOPT_FAILONERROR=>false,
|
CURLOPT_FAILONERROR=>false,
|
||||||
CURLOPT_FILE=>$fp,
|
CURLOPT_FILE=>$fp,
|
||||||
CURLOPT_USERAGENT=>'Bratonien-WebDAV-Cache-Worker/0.9.7.1.17',
|
CURLOPT_USERAGENT=>'Bratonien-WebDAV-Cache-Worker/0.9.7.1.30',
|
||||||
));
|
));
|
||||||
$ok = curl_exec($ch);
|
$ok = curl_exec($ch);
|
||||||
$errno = curl_errno($ch);
|
$errno = curl_errno($ch);
|
||||||
@@ -484,26 +494,70 @@ function bratonien_tools_cache_warmup_stage_pending(array $selected, array $inde
|
|||||||
return $pending;
|
return $pending;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function bratonien_tools_cache_warmup_stage_completed_count(array $selected, array $index, $stage)
|
||||||
|
{
|
||||||
|
return count($selected) - count(bratonien_tools_cache_warmup_stage_pending($selected, $index, $stage));
|
||||||
|
}
|
||||||
|
|
||||||
function bratonien_tools_cache_warmup_run_stage($connection_id, $stage, array $selected, array &$index, array $credentials, $batch_size, $priority_file='')
|
function bratonien_tools_cache_warmup_run_stage($connection_id, $stage, array $selected, array &$index, array $credentials, $batch_size, $priority_file='')
|
||||||
{
|
{
|
||||||
$pending = bratonien_tools_cache_warmup_stage_pending($selected, $index, $stage);
|
$pending = bratonien_tools_cache_warmup_stage_pending($selected, $index, $stage);
|
||||||
if (!$pending) return array('failed'=>0, 'preempted'=>false, 'completed'=>0);
|
if (!$pending) return array('failed'=>0, 'deferred'=>0, 'waiting'=>false, 'preempted'=>false, 'cancelled'=>false, 'completed'=>0);
|
||||||
|
if (bratonien_tools_cache_warmup_cancel_pending($connection_id))
|
||||||
|
{
|
||||||
|
return array('failed'=>0, 'deferred'=>0, 'waiting'=>false, 'preempted'=>false, 'cancelled'=>true, 'completed'=>0);
|
||||||
|
}
|
||||||
if ($stage === 2 && bratonien_tools_cache_warmup_priority_pending($priority_file))
|
if ($stage === 2 && bratonien_tools_cache_warmup_priority_pending($priority_file))
|
||||||
{
|
{
|
||||||
return array('failed'=>0, 'preempted'=>true, 'completed'=>0);
|
return array('failed'=>0, 'deferred'=>0, 'waiting'=>false, 'preempted'=>true, 'cancelled'=>false, 'completed'=>0);
|
||||||
}
|
}
|
||||||
|
|
||||||
$temp_root = PHPWG_ROOT_PATH.'upload/bratonien-webdav-warmup';
|
$temp_root = PHPWG_ROOT_PATH.'upload/bratonien-webdav-warmup';
|
||||||
if (!is_dir($temp_root) && !@mkdir($temp_root, 0775, true) && !is_dir($temp_root)) throw new RuntimeException('Worker-Temp-Verzeichnis konnte nicht angelegt werden.');
|
if (!is_dir($temp_root) && !@mkdir($temp_root, 0775, true) && !is_dir($temp_root)) throw new RuntimeException('Worker-Temp-Verzeichnis konnte nicht angelegt werden.');
|
||||||
$failed = 0;
|
$failed = 0;
|
||||||
|
$deferred = 0;
|
||||||
$completed = 0;
|
$completed = 0;
|
||||||
$batch_number = 0;
|
$batch_number = 0;
|
||||||
|
|
||||||
foreach (array_chunk(array_keys($pending), max(1, (int)$batch_size)) as $keys)
|
foreach (array_chunk(array_keys($pending), max(1, (int)$batch_size)) as $keys)
|
||||||
{
|
{
|
||||||
|
// Harte Batch-Grenze: Sobald ein Abbruchsignal existiert, darf dieser
|
||||||
|
// Batch gar nicht mehr begonnen und damit auch kein weiteres Original
|
||||||
|
// aus Nextcloud geladen werden.
|
||||||
|
if (bratonien_tools_cache_warmup_cancel_pending($connection_id))
|
||||||
|
{
|
||||||
|
return array('failed'=>$failed, 'deferred'=>$deferred, 'waiting'=>false, 'preempted'=>false, 'cancelled'=>true, 'completed'=>$completed);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($stage === 2 && bratonien_tools_cache_warmup_priority_pending($priority_file))
|
||||||
|
{
|
||||||
|
return array('failed'=>$failed, 'deferred'=>$deferred, 'waiting'=>false, 'preempted'=>true, 'cancelled'=>false, 'completed'=>$completed);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Der Connector-Lock wird VOR jedem Download geprueft und fuer den
|
||||||
|
// kompletten Batch gemeinsam gehalten. Ist der Connector aktiv, werden
|
||||||
|
// exakt null Bilder dieses Batches geladen.
|
||||||
|
$batch_sync_lock = null;
|
||||||
|
$batch_sync_detail = '';
|
||||||
|
if (!bratonien_tools_cache_warmup_sync_guard($credentials, $batch_sync_lock, $batch_sync_detail))
|
||||||
|
{
|
||||||
|
bratonien_tools_cache_warmup_status($connection_id, 'waiting', 'Connector-Synchronisierung läuft. Der nächste Batch startet erst danach; es wurden für diesen Batch keine Nextcloud-Originale geladen.', array(
|
||||||
|
'stage'=>$stage,
|
||||||
|
'batch'=>$batch_number + 1,
|
||||||
|
'selected_total'=>count($selected),
|
||||||
|
'stage_completed'=>$completed,
|
||||||
|
'deferred_by_connector'=>true,
|
||||||
|
));
|
||||||
|
return array('failed'=>$failed, 'deferred'=>$deferred, 'waiting'=>true, 'preempted'=>false, 'cancelled'=>false, 'completed'=>$completed);
|
||||||
|
}
|
||||||
|
|
||||||
$batch_number++;
|
$batch_number++;
|
||||||
$dir = $temp_root.'/connection-'.(int)$connection_id.'-stage'.$stage.'-'.date('YmdHis').'-'.bin2hex(random_bytes(4));
|
$dir = $temp_root.'/connection-'.(int)$connection_id.'-stage'.$stage.'-'.date('YmdHis').'-'.bin2hex(random_bytes(4));
|
||||||
if (!@mkdir($dir, 0775, true) && !is_dir($dir)) throw new RuntimeException('Worker-Batch-Verzeichnis konnte nicht angelegt werden.');
|
if (!@mkdir($dir, 0775, true) && !is_dir($dir))
|
||||||
|
{
|
||||||
|
bratonien_tools_cache_warmup_unlock($batch_sync_lock);
|
||||||
|
throw new RuntimeException('Worker-Batch-Verzeichnis konnte nicht angelegt werden.');
|
||||||
|
}
|
||||||
|
|
||||||
$downloads = array();
|
$downloads = array();
|
||||||
foreach ($keys as $key)
|
foreach ($keys as $key)
|
||||||
@@ -518,28 +572,42 @@ function bratonien_tools_cache_warmup_run_stage($connection_id, $stage, array $s
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bratonien_tools_cache_warmup_status($connection_id, 'running', 'Piwigo verarbeitet WebDAV-Quellen aus dem Worker-Index.', array(
|
$cancel_requested = bratonien_tools_cache_warmup_cancel_pending($connection_id);
|
||||||
|
bratonien_tools_cache_warmup_status(
|
||||||
|
$connection_id,
|
||||||
|
$cancel_requested ? 'cancelling' : 'running',
|
||||||
|
$cancel_requested
|
||||||
|
? 'Abbruch angefordert. Der bereits geladene aktuelle Batch wird vollständig beendet; danach ist Schluss.'
|
||||||
|
: 'Piwigo verarbeitet WebDAV-Quellen aus dem Worker-Index.',
|
||||||
|
array(
|
||||||
'stage'=>$stage,
|
'stage'=>$stage,
|
||||||
'batch'=>$batch_number,
|
'batch'=>$batch_number,
|
||||||
'batch_requested'=>count($keys),
|
'batch_requested'=>count($keys),
|
||||||
'batch_downloaded'=>count($downloads),
|
'batch_downloaded'=>count($downloads),
|
||||||
'selected_total'=>count($selected),
|
'selected_total'=>count($selected),
|
||||||
'stage_completed'=>$completed,
|
'stage_completed'=>$completed,
|
||||||
));
|
'cancel_requested'=>$cancel_requested,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
foreach ($downloads as $key=>$file)
|
foreach ($downloads as $key=>$file)
|
||||||
{
|
{
|
||||||
$result = bratonien_tools_cache_warmup_process($pending[$key], $file, $credentials, $stage);
|
$result = bratonien_tools_cache_warmup_process($pending[$key], $file, $credentials, $stage);
|
||||||
bratonien_tools_cache_warmup_log('source', array('stage'=>$stage, 'source'=>$key, 'ok'=>!empty($result['ok']), 'message'=>(string)($result['message'] ?? '')));
|
bratonien_tools_cache_warmup_log('source', array('stage'=>$stage, 'source'=>$key, 'ok'=>!empty($result['ok']), 'defer'=>!empty($result['defer']), 'message'=>(string)($result['message'] ?? '')));
|
||||||
if (!empty($result['fatal']))
|
if (!empty($result['fatal']))
|
||||||
{
|
{
|
||||||
foreach ($downloads as $cleanup) @unlink($cleanup);
|
foreach ($downloads as $cleanup) @unlink($cleanup);
|
||||||
@rmdir($dir);
|
@rmdir($dir);
|
||||||
|
bratonien_tools_cache_warmup_unlock($batch_sync_lock);
|
||||||
throw new RuntimeException('Sicherheitsabbruch bei '.$key.': '.(string)$result['message']);
|
throw new RuntimeException('Sicherheitsabbruch bei '.$key.': '.(string)$result['message']);
|
||||||
}
|
}
|
||||||
if (empty($result['ok']))
|
if (empty($result['ok']))
|
||||||
{
|
{
|
||||||
$failed++;
|
// Temporäre Sperren oder parallel belegte Quellen sind kein Fehler.
|
||||||
|
// Der Index bleibt offen und der nächste Lauf versucht nur diese
|
||||||
|
// Quelle erneut.
|
||||||
|
if (!empty($result['defer'])) $deferred++;
|
||||||
|
else $failed++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -554,14 +622,20 @@ function bratonien_tools_cache_warmup_run_stage($connection_id, $stage, array $s
|
|||||||
|
|
||||||
foreach ($downloads as $file) @unlink($file);
|
foreach ($downloads as $file) @unlink($file);
|
||||||
@rmdir($dir);
|
@rmdir($dir);
|
||||||
|
bratonien_tools_cache_warmup_unlock($batch_sync_lock);
|
||||||
|
|
||||||
|
if (bratonien_tools_cache_warmup_cancel_pending($connection_id))
|
||||||
|
{
|
||||||
|
return array('failed'=>$failed, 'deferred'=>$deferred, 'waiting'=>false, 'preempted'=>false, 'cancelled'=>true, 'completed'=>$completed);
|
||||||
|
}
|
||||||
|
|
||||||
if ($stage === 2 && bratonien_tools_cache_warmup_priority_pending($priority_file))
|
if ($stage === 2 && bratonien_tools_cache_warmup_priority_pending($priority_file))
|
||||||
{
|
{
|
||||||
return array('failed'=>$failed, 'preempted'=>true, 'completed'=>$completed);
|
return array('failed'=>$failed, 'deferred'=>$deferred, 'waiting'=>false, 'preempted'=>true, 'cancelled'=>false, 'completed'=>$completed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return array('failed'=>$failed, 'preempted'=>false, 'completed'=>$completed);
|
return array('failed'=>$failed, 'deferred'=>$deferred, 'waiting'=>false, 'preempted'=>false, 'cancelled'=>false, 'completed'=>$completed);
|
||||||
}
|
}
|
||||||
|
|
||||||
function bratonien_tools_cache_warmup_run($connection_id, $mode)
|
function bratonien_tools_cache_warmup_run($connection_id, $mode)
|
||||||
@@ -618,6 +692,7 @@ function bratonien_tools_cache_warmup_run($connection_id, $mode)
|
|||||||
{
|
{
|
||||||
if ($mode === 'periodic' || $mode === 'manual') $index['last_periodic_at'] = time();
|
if ($mode === 'periodic' || $mode === 'manual') $index['last_periodic_at'] = time();
|
||||||
bratonien_tools_webdav_source_index_save($state_dir, $connection_id, $index);
|
bratonien_tools_webdav_source_index_save($state_dir, $connection_id, $index);
|
||||||
|
@unlink(bratonien_tools_cache_warmup_cancel_file($connection_id));
|
||||||
bratonien_tools_cache_warmup_status($connection_id, 'complete', 'Keine neuen oder geänderten Shadow-Quellen gefunden.', array('mode'=>$mode, 'shadow_sources'=>count($scan['sources'])));
|
bratonien_tools_cache_warmup_status($connection_id, 'complete', 'Keine neuen oder geänderten Shadow-Quellen gefunden.', array('mode'=>$mode, 'shadow_sources'=>count($scan['sources'])));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -632,6 +707,29 @@ function bratonien_tools_cache_warmup_run($connection_id, $mode)
|
|||||||
}
|
}
|
||||||
|
|
||||||
$stage1 = bratonien_tools_cache_warmup_run_stage($connection_id, 1, $selected, $index, $credentials, $settings['batch_size'], $priority_file);
|
$stage1 = bratonien_tools_cache_warmup_run_stage($connection_id, 1, $selected, $index, $credentials, $settings['batch_size'], $priority_file);
|
||||||
|
if (!empty($stage1['cancelled']))
|
||||||
|
{
|
||||||
|
bratonien_tools_webdav_source_index_save($state_dir, $connection_id, $index);
|
||||||
|
@unlink(bratonien_tools_cache_warmup_cancel_file($connection_id));
|
||||||
|
bratonien_tools_cache_warmup_status($connection_id, 'cancelled', 'Cache-Aufbau nach dem vollständig abgeschlossenen aktuellen Batch beendet.', array(
|
||||||
|
'mode'=>$mode,
|
||||||
|
'shadow_sources'=>count($scan['sources']),
|
||||||
|
'selected'=>count($selected),
|
||||||
|
'stage1_completed'=>bratonien_tools_cache_warmup_stage_completed_count($selected, $index, 1),
|
||||||
|
'stage2_completed'=>bratonien_tools_cache_warmup_stage_completed_count($selected, $index, 2),
|
||||||
|
'stage1_failed'=>(int)$stage1['failed'],
|
||||||
|
'stage1_deferred'=>(int)$stage1['deferred'],
|
||||||
|
'stage2_failed'=>0,
|
||||||
|
'stage2_deferred'=>0,
|
||||||
|
));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (!empty($stage1['waiting']))
|
||||||
|
{
|
||||||
|
bratonien_tools_webdav_source_index_save($state_dir, $connection_id, $index);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
$stage2_candidates = array();
|
$stage2_candidates = array();
|
||||||
foreach ($selected as $key=>$item)
|
foreach ($selected as $key=>$item)
|
||||||
{
|
{
|
||||||
@@ -640,30 +738,79 @@ function bratonien_tools_cache_warmup_run($connection_id, $mode)
|
|||||||
}
|
}
|
||||||
$stage2 = bratonien_tools_cache_warmup_run_stage($connection_id, 2, $stage2_candidates, $index, $credentials, $settings['batch_size'], $priority_file);
|
$stage2 = bratonien_tools_cache_warmup_run_stage($connection_id, 2, $stage2_candidates, $index, $credentials, $settings['batch_size'], $priority_file);
|
||||||
|
|
||||||
|
if (!empty($stage2['cancelled']))
|
||||||
|
{
|
||||||
|
bratonien_tools_webdav_source_index_save($state_dir, $connection_id, $index);
|
||||||
|
@unlink(bratonien_tools_cache_warmup_cancel_file($connection_id));
|
||||||
|
bratonien_tools_cache_warmup_status($connection_id, 'cancelled', 'Cache-Aufbau nach dem vollständig abgeschlossenen aktuellen Batch beendet.', array(
|
||||||
|
'mode'=>$mode,
|
||||||
|
'shadow_sources'=>count($scan['sources']),
|
||||||
|
'selected'=>count($selected),
|
||||||
|
'stage1_completed'=>bratonien_tools_cache_warmup_stage_completed_count($selected, $index, 1),
|
||||||
|
'stage2_completed'=>bratonien_tools_cache_warmup_stage_completed_count($selected, $index, 2),
|
||||||
|
'stage1_failed'=>(int)$stage1['failed'],
|
||||||
|
'stage1_deferred'=>(int)$stage1['deferred'],
|
||||||
|
'stage2_failed'=>(int)$stage2['failed'],
|
||||||
|
'stage2_deferred'=>(int)$stage2['deferred'],
|
||||||
|
));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (!empty($stage2['waiting']))
|
||||||
|
{
|
||||||
|
bratonien_tools_webdav_source_index_save($state_dir, $connection_id, $index);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (!empty($stage2['preempted']))
|
if (!empty($stage2['preempted']))
|
||||||
{
|
{
|
||||||
|
bratonien_tools_webdav_source_index_save($state_dir, $connection_id, $index);
|
||||||
bratonien_tools_cache_warmup_status($connection_id, 'preempted', 'Stufe 2 wurde nach einem vollständigen Batch für neue Connector-Inhalte freigegeben.', array(
|
bratonien_tools_cache_warmup_status($connection_id, 'preempted', 'Stufe 2 wurde nach einem vollständigen Batch für neue Connector-Inhalte freigegeben.', array(
|
||||||
'mode'=>$mode,
|
'mode'=>$mode,
|
||||||
|
'selected'=>count($selected),
|
||||||
|
'stage1_completed'=>bratonien_tools_cache_warmup_stage_completed_count($selected, $index, 1),
|
||||||
|
'stage2_completed'=>bratonien_tools_cache_warmup_stage_completed_count($selected, $index, 2),
|
||||||
'stage1_failed'=>(int)$stage1['failed'],
|
'stage1_failed'=>(int)$stage1['failed'],
|
||||||
|
'stage1_deferred'=>(int)$stage1['deferred'],
|
||||||
'stage2_failed'=>(int)$stage2['failed'],
|
'stage2_failed'=>(int)$stage2['failed'],
|
||||||
|
'stage2_deferred'=>(int)$stage2['deferred'],
|
||||||
));
|
));
|
||||||
return ((int)$stage1['failed'] + (int)$stage2['failed']) > 0 ? 2 : 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($mode === 'periodic' || $mode === 'manual') $index['last_periodic_at'] = time();
|
if ($mode === 'periodic' || $mode === 'manual') $index['last_periodic_at'] = time();
|
||||||
bratonien_tools_webdav_source_index_save($state_dir, $connection_id, $index);
|
bratonien_tools_webdav_source_index_save($state_dir, $connection_id, $index);
|
||||||
|
@unlink(bratonien_tools_cache_warmup_cancel_file($connection_id));
|
||||||
|
|
||||||
$failed = (int)$stage1['failed'] + (int)$stage2['failed'];
|
$failed = (int)$stage1['failed'] + (int)$stage2['failed'];
|
||||||
bratonien_tools_cache_warmup_status($connection_id, $failed ? 'error' : 'complete', $failed ? 'Worker-Lauf mit einzelnen Fehlern beendet.' : ($mode === 'rebuild' ? 'Piwigo hat den vollständigen Shadow-Bestand für den Cache-Rebuild verarbeitet.' : 'Worker-Lauf vollständig beendet.'), array(
|
$deferred = (int)$stage1['deferred'] + (int)$stage2['deferred'];
|
||||||
|
if ($failed > 0 || $deferred > 0)
|
||||||
|
{
|
||||||
|
bratonien_tools_cache_warmup_status($connection_id, 'partial', 'Worker-Lauf beendet; einzelne Quellen bleiben offen und werden beim nächsten Lauf erneut versucht. Der übrige Bestand wurde weiterverarbeitet.', array(
|
||||||
'mode'=>$mode,
|
'mode'=>$mode,
|
||||||
'shadow_sources'=>count($scan['sources']),
|
'shadow_sources'=>count($scan['sources']),
|
||||||
'selected'=>count($selected),
|
'selected'=>count($selected),
|
||||||
'stage1_completed'=>(int)$stage1['completed'],
|
'stage1_completed'=>bratonien_tools_cache_warmup_stage_completed_count($selected, $index, 1),
|
||||||
'stage2_completed'=>(int)$stage2['completed'],
|
'stage2_completed'=>bratonien_tools_cache_warmup_stage_completed_count($selected, $index, 2),
|
||||||
'stage1_failed'=>(int)$stage1['failed'],
|
'stage1_failed'=>(int)$stage1['failed'],
|
||||||
|
'stage1_deferred'=>(int)$stage1['deferred'],
|
||||||
'stage2_failed'=>(int)$stage2['failed'],
|
'stage2_failed'=>(int)$stage2['failed'],
|
||||||
|
'stage2_deferred'=>(int)$stage2['deferred'],
|
||||||
));
|
));
|
||||||
return $failed ? 2 : 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bratonien_tools_cache_warmup_status($connection_id, 'complete', $mode === 'rebuild' ? 'Piwigo hat den vollständigen Shadow-Bestand für den Cache-Rebuild verarbeitet.' : 'Worker-Lauf vollständig beendet.', array(
|
||||||
|
'mode'=>$mode,
|
||||||
|
'shadow_sources'=>count($scan['sources']),
|
||||||
|
'selected'=>count($selected),
|
||||||
|
'stage1_completed'=>bratonien_tools_cache_warmup_stage_completed_count($selected, $index, 1),
|
||||||
|
'stage2_completed'=>bratonien_tools_cache_warmup_stage_completed_count($selected, $index, 2),
|
||||||
|
'stage1_failed'=>0,
|
||||||
|
'stage1_deferred'=>0,
|
||||||
|
'stage2_failed'=>0,
|
||||||
|
'stage2_deferred'=>0,
|
||||||
|
));
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ $_SERVER['REQUEST_URI'] = '/';
|
|||||||
$_SERVER['SCRIPT_NAME'] = '/plugins/bratonien_tools/runtime/webdav-warmup-dispatch.php';
|
$_SERVER['SCRIPT_NAME'] = '/plugins/bratonien_tools/runtime/webdav-warmup-dispatch.php';
|
||||||
$_SERVER['PHP_SELF'] = $_SERVER['SCRIPT_NAME'];
|
$_SERVER['PHP_SELF'] = $_SERVER['SCRIPT_NAME'];
|
||||||
$_SERVER['QUERY_STRING'] = '';
|
$_SERVER['QUERY_STRING'] = '';
|
||||||
$_SERVER['HTTP_USER_AGENT'] = 'Bratonien-WebDAV-Worker-Dispatcher/0.9.7.1.23';
|
$_SERVER['HTTP_USER_AGENT'] = 'Bratonien-WebDAV-Worker-Dispatcher/0.9.7.1.29';
|
||||||
$_SERVER['HTTPS'] = 'off';
|
$_SERVER['HTTPS'] = 'off';
|
||||||
|
|
||||||
require_once(PHPWG_ROOT_PATH.'include/common.inc.php');
|
require_once(PHPWG_ROOT_PATH.'include/common.inc.php');
|
||||||
@@ -66,6 +66,43 @@ function bratonien_tools_webdav_dispatch_failure_lines(array $output)
|
|||||||
return $failures;
|
return $failures;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function bratonien_tools_webdav_dispatch_only_connector_deferrals(array $output)
|
||||||
|
{
|
||||||
|
$seen = false;
|
||||||
|
foreach ($output as $line)
|
||||||
|
{
|
||||||
|
$line = trim((string)$line);
|
||||||
|
if ($line === '') continue;
|
||||||
|
if (strpos($line, '[BRAT-WORKER] fatal ') !== false || strpos($line, 'download_failed') !== false || stripos($line, 'RESTORE FEHLGESCHLAGEN') !== false)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (strpos($line, ' ok=0 ') !== false)
|
||||||
|
{
|
||||||
|
$seen = true;
|
||||||
|
if (strpos($line, 'message=Connector-Synchronisierung läuft.') === false && strpos($line, 'message=Connector-Mapping hat sich seit dem Batch-Download geändert.') === false && strpos($line, 'message=Shadow-Tree hat sich seit dem Batch-Download geändert.') === false)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $seen;
|
||||||
|
}
|
||||||
|
|
||||||
|
function bratonien_tools_webdav_dispatch_connector_busy($state_dir)
|
||||||
|
{
|
||||||
|
$lock = @fopen(rtrim((string)$state_dir, '/').'/webdav-sync.lock', 'c');
|
||||||
|
if (!$lock) return false;
|
||||||
|
if (@flock($lock, LOCK_SH | LOCK_NB))
|
||||||
|
{
|
||||||
|
@flock($lock, LOCK_UN);
|
||||||
|
fclose($lock);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
fclose($lock);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
$mode = 'periodic';
|
$mode = 'periodic';
|
||||||
$wait = false;
|
$wait = false;
|
||||||
$connection_filter = 0;
|
$connection_filter = 0;
|
||||||
@@ -147,6 +184,20 @@ foreach (bratonien_tools_nc_connector_connections() as $connection)
|
|||||||
}
|
}
|
||||||
@chmod($priority_file, 0664);
|
@chmod($priority_file, 0664);
|
||||||
}
|
}
|
||||||
|
elseif (bratonien_tools_webdav_dispatch_connector_busy($state_dir))
|
||||||
|
{
|
||||||
|
if (function_exists('bratonien_tools_webdav_warmup_write_status'))
|
||||||
|
{
|
||||||
|
bratonien_tools_webdav_warmup_write_status(
|
||||||
|
$connection_id,
|
||||||
|
'waiting',
|
||||||
|
'Connector-Synchronisierung läuft. Der Cache-Worker startet erst danach; es werden vorher keine Nextcloud-Originale geladen.',
|
||||||
|
array('mode'=>$mode, 'deferred_by_connector'=>true)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
fwrite(STDOUT, "WebDAV-Worker für Verbindung #{$connection_id} wartet auf den Connector-Sync.\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
$worker_command = escapeshellarg(PHP_BINARY).' '.escapeshellarg($worker)
|
$worker_command = escapeshellarg(PHP_BINARY).' '.escapeshellarg($worker)
|
||||||
.' --connection-id='.$connection_id
|
.' --connection-id='.$connection_id
|
||||||
@@ -167,12 +218,32 @@ foreach (bratonien_tools_nc_connector_connections() as $connection)
|
|||||||
}
|
}
|
||||||
if ($exit !== 0)
|
if ($exit !== 0)
|
||||||
{
|
{
|
||||||
|
$deferred = bratonien_tools_webdav_dispatch_only_connector_deferrals($output);
|
||||||
|
if ($deferred)
|
||||||
|
{
|
||||||
|
if (function_exists('bratonien_tools_webdav_warmup_write_status'))
|
||||||
|
{
|
||||||
|
$existing = bratonien_tools_webdav_dispatch_existing_status($connection_id);
|
||||||
|
$extra = is_array($existing) ? $existing : array();
|
||||||
|
unset($extra['state'], $extra['message'], $extra['connection_id'], $extra['updated_at']);
|
||||||
|
$extra['worker_exit_code'] = (int)$exit;
|
||||||
|
$extra['deferred_by_connector'] = true;
|
||||||
|
bratonien_tools_webdav_warmup_write_status(
|
||||||
|
$connection_id,
|
||||||
|
'waiting',
|
||||||
|
'Connector-Synchronisierung hat während des Batches Vorrang erhalten. Der bisherige Indexstand bleibt erhalten; die offenen Quellen werden später fortgesetzt und gelten nicht als Fehler.',
|
||||||
|
$extra
|
||||||
|
);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
$result = $exit;
|
$result = $exit;
|
||||||
if (function_exists('bratonien_tools_webdav_warmup_write_status'))
|
if (function_exists('bratonien_tools_webdav_warmup_write_status'))
|
||||||
{
|
{
|
||||||
$existing = bratonien_tools_webdav_dispatch_existing_status($connection_id);
|
$existing = bratonien_tools_webdav_dispatch_existing_status($connection_id);
|
||||||
$failures = bratonien_tools_webdav_dispatch_failure_lines($output);
|
$failures = bratonien_tools_webdav_dispatch_failure_lines($output);
|
||||||
$terminal = is_array($existing) && in_array((string)($existing['state'] ?? ''), array('error','fatal','preempted'), true);
|
$terminal = is_array($existing) && in_array((string)($existing['state'] ?? ''), array('error','fatal','preempted','cancelled'), true);
|
||||||
|
|
||||||
if ($terminal)
|
if ($terminal)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user