#!/bin/sh
# Der Tunnel und der Arbeiter, die sich einen Container teilen — aber nicht
# mehr ein Schicksal.
#
# Bis hierher war `php artisan queue:work` der Prozess 1 dieses Containers.
# Damit hing wg0 an seinem Leben: jedes Mal, wenn der Arbeiter endete, endete
# der Container, und mit ihm der Netz-Namensraum, in dem der Tunnel steht.
#
# Ein Arbeiter endet oefter, als man denkt. `--timeout=2100` beendet ihn, wenn
# ein Provisionierungs-Schritt zu lange braucht. Ein fataler Fehler beendet ihn.
# Ein ueberschrittenes Speicherlimit beendet ihn. `queue:restart` beendet ihn
# absichtlich. In allen vier Faellen fielen bisher saemtliche WireGuard-Sitzungen
# mit — die des Betreibers am Telefon genauso wie die jedes Hosts. Von aussen sah
# das aus wie „das VPN ist unzuverlaessig", und die Ursache stand in einer Zeile
# docker-compose.yml, die von Warteschlangen handelt.
#
# Deshalb laeuft der Arbeiter in einer Schleife: faellt er, kommt er wieder.
# Seit wg0 im eigenen Container vpn-hub wohnt, ist das die zweite Sicherung —
# die erste ist, dass dieser Container den Namensraum gar nicht mehr besitzt.
#
# Der Container endet dann nur noch, wenn Docker ihn beendet. Das ist Absicht:
# ein Arbeiter, der nicht startet, ist ein Fall fuers Protokoll, kein Grund,
# jedem Host die Verbindung abzuschneiden.
set -u

# wg0 wird NICHT mehr hier hochgezogen — das tut der vpn-hub, dessen
# Netz-Namensraum dieser Container nur noch mitbenutzt. Der Tunnel haengt damit
# nicht mehr am Veroeffentlichungstakt der Anwendung.

# SIGTERM sauber weiterreichen: sonst wartet `docker compose stop` zehn Sekunden
# und schlaegt dann mit SIGKILL zu — mitten in einem Provisionierungs-Schritt.
child=''
stop() {
    [ -n "$child" ] && kill -TERM "$child" 2>/dev/null
    exit 0
}
trap stop TERM INT

while true; do
    php artisan queue:work provisioning \
        --queue=provisioning \
        --tries=1 \
        --timeout=2100 \
        --sleep=3 &
    child=$!
    wait "$child"
    code=$?

    # Ins Protokoll, nicht ins Nichts: ein Arbeiter, der staendig neu startet,
    # ist ein eigenes Problem — es soll nur nicht mehr das Problem des Tunnels
    # sein.
    echo "[provisioning] Arbeiter beendet (Code ${code}) — wg0 bleibt oben, Neustart in 2 s" >&2
    sleep 2
done
