fix(PROJ-58): Lockfile gegen überlappende Cron-Batch-Läufe + update.sh synct Cron-Dateien
Root Cause für ausbleibende Lastsenkung: update.sh hat /etc/cron.d/archivmail nie auf den Server kopiert, daher fehlten die PROJ-58-Cronzeilen trotz aktivem batch_mode komplett. Jetzt kopiert update.sh die Cron-Datei und alle Wrapper-Skripte bei jedem Deploy automatisch ein. Zusätzlich: Wrapper-Skripte (analog mailpiler indexer.delta.sh) verhindern per Lockfile, dass sich Cron-Läufe bei großem Backlog überlappen. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
c91eeac0a0
commit
46502abe75
@@ -46,15 +46,22 @@
|
|||||||
# dauerhaft und arbeitet alles sofort ab. Wer batch_mode nicht nutzt, kann
|
# dauerhaft und arbeitet alles sofort ab. Wer batch_mode nicht nutzt, kann
|
||||||
# die beiden Zeilen einfach auskommentiert lassen.
|
# die beiden Zeilen einfach auskommentiert lassen.
|
||||||
#
|
#
|
||||||
|
# Die Jobs rufen Wrapper-Skripte auf (archivmail-index-pending.sh /
|
||||||
|
# archivmail-ocr-reprocess.sh), die per PID-Lockfile unter /var/run/archivmail/
|
||||||
|
# überlappende Läufe verhindern — analog zum mailpiler-Vorbild
|
||||||
|
# (indexer.delta.sh mit MAINTMPFILE/DELTATMPFILE). Ohne diesen Schutz könnte
|
||||||
|
# ein Lauf mit großem Backlog länger dauern als das Intervall und sich mit
|
||||||
|
# dem nächsten Tick überlappen, was die Last-Glättung wieder aufheben würde.
|
||||||
|
#
|
||||||
# Anpassen: Intervall/Uhrzeiten unten nach Bedarf ändern (crontab-Syntax).
|
# Anpassen: Intervall/Uhrzeiten unten nach Bedarf ändern (crontab-Syntax).
|
||||||
# Die beiden Jobs sind bewusst leicht versetzt, damit Index- und OCR-Lauf
|
# Die beiden Jobs sind bewusst leicht versetzt, damit Index- und OCR-Lauf
|
||||||
# nicht exakt zeitgleich starten.
|
# nicht exakt zeitgleich starten.
|
||||||
|
|
||||||
# Index-Backlog (indexed_at IS NULL) alle 15 Minuten verarbeiten
|
# Index-Backlog (indexed_at IS NULL) alle 15 Minuten verarbeiten
|
||||||
*/15 * * * * root /opt/archivmail/archivmail index-pending --config /etc/archivmail/config.yml --limit 500 >> /var/log/archivmail/index-pending.log 2>&1
|
*/15 * * * * root /usr/local/bin/archivmail-index-pending.sh >> /var/log/archivmail/index-pending.log 2>&1
|
||||||
|
|
||||||
# OCR-Backlog (ocr_status='pending') alle 15 Minuten, um 5 Min versetzt
|
# OCR-Backlog (ocr_status='pending') alle 15 Minuten, um 5 Min versetzt
|
||||||
5,20,35,50 * * * * root /opt/archivmail/archivmail ocr-reprocess --config /etc/archivmail/config.yml --status pending --limit 500 >> /var/log/archivmail/ocr-reprocess.log 2>&1
|
5,20,35,50 * * * * root /usr/local/bin/archivmail-ocr-reprocess.sh >> /var/log/archivmail/ocr-reprocess.log 2>&1
|
||||||
|
|
||||||
# ── Weitere Jobs (geplant, noch nicht implementiert) ────────────────────
|
# ── Weitere Jobs (geplant, noch nicht implementiert) ────────────────────
|
||||||
# 30 2 * * * archivmail /opt/archivmail/archivmail reindex # nächtlicher Voll-Reindex
|
# 30 2 * * * archivmail /opt/archivmail/archivmail reindex # nächtlicher Voll-Reindex
|
||||||
|
|||||||
Executable
+25
@@ -0,0 +1,25 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# archivmail — Cron-Wrapper für 'index-pending' (PROJ-58 batch_mode).
|
||||||
|
#
|
||||||
|
# Verhindert überlappende Läufe per PID-Lockfile, analog zum mailpiler-Vorbild
|
||||||
|
# (/usr/libexec/piler/indexer.delta.sh, MAINTMPFILE/DELTATMPFILE-Muster):
|
||||||
|
# Läuft ein Cron-Job länger als das Intervall (z.B. großer Backlog), würde
|
||||||
|
# sonst ein zweiter, parallel gestarteter Lauf zusätzliche Last erzeugen statt
|
||||||
|
# sie zu glätten — genau das soll batch_mode ja vermeiden.
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
LOCKFILE=/var/run/archivmail/index-pending.lock
|
||||||
|
LOGTAG=archivmail-index-pending
|
||||||
|
mkdir -p "$(dirname "$LOCKFILE")"
|
||||||
|
|
||||||
|
if [[ -f "$LOCKFILE" ]]; then
|
||||||
|
echo "INDEX-PENDING ERROR: bereits laufender Lauf seit $(cat "$LOCKFILE")" | logger -t "$LOGTAG"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
date > "$LOCKFILE"
|
||||||
|
trap 'rm -f "$LOCKFILE"' EXIT
|
||||||
|
|
||||||
|
echo "INDEX-PENDING INFO: Lauf gestartet" | logger -t "$LOGTAG"
|
||||||
|
/opt/archivmail/archivmail index-pending --config /etc/archivmail/config.yml --limit "${ARCHIVMAIL_INDEX_LIMIT:-500}"
|
||||||
|
echo "INDEX-PENDING INFO: Lauf beendet" | logger -t "$LOGTAG"
|
||||||
Executable
+21
@@ -0,0 +1,21 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# archivmail — Cron-Wrapper für 'ocr-reprocess --status pending' (PROJ-58
|
||||||
|
# batch_mode). Lockfile-Schutz gegen überlappende Läufe, siehe
|
||||||
|
# archivmail-index-pending.sh für die ausführliche Begründung.
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
LOCKFILE=/var/run/archivmail/ocr-reprocess.lock
|
||||||
|
LOGTAG=archivmail-ocr-reprocess
|
||||||
|
mkdir -p "$(dirname "$LOCKFILE")"
|
||||||
|
|
||||||
|
if [[ -f "$LOCKFILE" ]]; then
|
||||||
|
echo "OCR-REPROCESS ERROR: bereits laufender Lauf seit $(cat "$LOCKFILE")" | logger -t "$LOGTAG"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
date > "$LOCKFILE"
|
||||||
|
trap 'rm -f "$LOCKFILE"' EXIT
|
||||||
|
|
||||||
|
echo "OCR-REPROCESS INFO: Lauf gestartet" | logger -t "$LOGTAG"
|
||||||
|
/opt/archivmail/archivmail ocr-reprocess --config /etc/archivmail/config.yml --status pending --limit "${ARCHIVMAIL_OCR_LIMIT:-500}"
|
||||||
|
echo "OCR-REPROCESS INFO: Lauf beendet" | logger -t "$LOGTAG"
|
||||||
@@ -59,6 +59,12 @@ Aktuell laufen Indexierung (`internal/index/tenant_worker.go`) und OCR (`interna
|
|||||||
- Minor-Finding behoben: `index-pending` fehlte in `printHelp()` (cmd_import.go) — ergänzt.
|
- Minor-Finding behoben: `index-pending` fehlte in `printHelp()` (cmd_import.go) — ergänzt.
|
||||||
- Keine Critical/High-Findings. Server 192.168.1.131 nicht angefasst während der QA.
|
- Keine Critical/High-Findings. Server 192.168.1.131 nicht angefasst während der QA.
|
||||||
|
|
||||||
|
## Nachtrag (2026-06-24): Lockfile-Schutz gegen überlappende Cron-Läufe
|
||||||
|
Nutzer wies auf mailpiler-Vorbild hin (`indexer.delta.sh`, PID-Lockfile-Muster), um zu verhindern, dass sich Cron-Läufe bei großem Backlog überlappen (würde die Last-Glättung wieder aufheben). Umgesetzt:
|
||||||
|
- Neue Wrapper-Skripte `deploy/cron.d/archivmail-index-pending.sh` und `deploy/cron.d/archivmail-ocr-reprocess.sh` — Lockfile unter `/var/run/archivmail/*.lock`, analog zu Pilers `MAINTMPFILE`/`DELTATMPFILE`-Muster (Datei mit Zeitstempel statt PID, da `trap ... EXIT` zuverlässig aufräumt; bei bereits laufendem Lauf wird einfach übersprungen statt zu warten/abzubrechen mit Fehlercode, damit Cron keine Fehlermail wegen "schon belegt" verschickt).
|
||||||
|
- `deploy/cron.d/archivmail` ruft jetzt die Wrapper-Skripte unter `/usr/local/bin/` auf statt das Binary direkt.
|
||||||
|
- **Root Cause für "Last geht nicht runter" gefunden:** `update.sh` synct `/etc/cron.d/archivmail` nie auf den Server — die PROJ-58-Cronzeilen fehlten auf 131 UND 132 komplett, obwohl `batch_mode` im Code bereits aktiv war. Daher lief weiterhin nichts batch-weise, weil der Backlog nie per Cron abgeholt wurde. Fix: `update.sh` kopiert jetzt `deploy/cron.d/archivmail` nach `/etc/cron.d/archivmail` und alle `deploy/cron.d/*.sh`-Wrapper nach `/usr/local/bin/` bei jedem Deploy.
|
||||||
|
|
||||||
## Nachtrag (2026-06-24): batch_mode als Default für Neuinstallationen
|
## Nachtrag (2026-06-24): batch_mode als Default für Neuinstallationen
|
||||||
Auf Nutzerwunsch ist `index.batch_mode: true` und `ocr.batch_mode: true` jetzt aktiv (nicht mehr auskommentiert) in `config/config.docker.yml.example` gesetzt, damit neue Installationen direkt mit Cron-Batch statt Dauerbetrieb starten. Bestehende Installationen (wie 192.168.1.131/132) sind davon nicht betroffen, da deren `/etc/archivmail/config.yml` unabhängig vom Repo-Beispiel ist und weiterhin ohne `batch_mode`-Einträge (= Dauerbetrieb) läuft.
|
Auf Nutzerwunsch ist `index.batch_mode: true` und `ocr.batch_mode: true` jetzt aktiv (nicht mehr auskommentiert) in `config/config.docker.yml.example` gesetzt, damit neue Installationen direkt mit Cron-Batch statt Dauerbetrieb starten. Bestehende Installationen (wie 192.168.1.131/132) sind davon nicht betroffen, da deren `/etc/archivmail/config.yml` unabhängig vom Repo-Beispiel ist und weiterhin ohne `batch_mode`-Einträge (= Dauerbetrieb) läuft.
|
||||||
|
|
||||||
|
|||||||
@@ -160,6 +160,15 @@ cp "$BIN_DIR/archivmail" "$INSTALL_DIR/archivmail"
|
|||||||
ln -sf "$BIN_DIR/archivmail" /usr/local/bin/archivmail
|
ln -sf "$BIN_DIR/archivmail" /usr/local/bin/archivmail
|
||||||
log "Backend eingespielt"
|
log "Backend eingespielt"
|
||||||
|
|
||||||
|
info "Spiele Cron-Jobs ein..."
|
||||||
|
cp "$BUILD_DIR/deploy/cron.d/archivmail" /etc/cron.d/archivmail
|
||||||
|
chmod 644 /etc/cron.d/archivmail
|
||||||
|
for script in "$BUILD_DIR"/deploy/cron.d/*.sh; do
|
||||||
|
cp "$script" "/usr/local/bin/$(basename "$script")"
|
||||||
|
chmod 755 "/usr/local/bin/$(basename "$script")"
|
||||||
|
done
|
||||||
|
log "Cron-Jobs eingespielt (/etc/cron.d/archivmail + Wrapper-Skripte)"
|
||||||
|
|
||||||
info "Spiele Frontend ein (standalone)..."
|
info "Spiele Frontend ein (standalone)..."
|
||||||
# Next.js standalone mirrors the absolute build path — find the dir that contains server.js.
|
# Next.js standalone mirrors the absolute build path — find the dir that contains server.js.
|
||||||
# The path is typically: .next/standalone/<build-dir>/server.js
|
# The path is typically: .next/standalone/<build-dir>/server.js
|
||||||
|
|||||||
Reference in New Issue
Block a user