mirror of
https://github.com/projectsend/projectsend.git
synced 2026-09-20 02:23:20 +00:00
Have the updater repair a worker that predates the zips queue
Splitting zip builds onto their own queue (92a132d) left manual installs
carrying the one job the release note has to do, and the failure it
produces is the worst shape available: a worker still watching only
`default` sends every email cheerfully and finishes no zip downloads,
with nothing in any log to say why. An upgrade note is a poor place to
put that, because it is read on a laptop and needed on a server.
update.sh already finds projectsend-worker.service, so it now reads the
unit's ExecStart and offers to add --queue=default,zips, keeping a copy
of the original beside it. Before the restart, so the worker comes back
on the command it is going to keep.
Only the unambiguous case is rewritten: a queue:work line with no
--queue at all, which consumes `default` and nothing else. A unit that
already names its queues is somebody's deliberate arrangement, possibly
with a second worker for zips, so that one is described rather than
edited — and one that already includes zips is silently left alone.
Exercised against five unit shapes rather than reasoned about: the plain
command is rewritten and backed up, a declined prompt leaves it untouched
with a warning, a unit already naming zips is a no-op, a custom queue list
without zips warns instead of editing, and a unit that is not queue:work
at all is ignored. The sed itself would double-append if it ran twice;
it cannot, because the --queue= guard above it returns first, and both
read the same first ExecStart line.
This commit is contained in:
+7
-6
@@ -41,12 +41,13 @@ a version is cut.
|
||||
email behind it. Zip building now has a queue of its own, and the Docker images run a second
|
||||
background worker for it.
|
||||
|
||||
**Upgrade note, manual installs only:** your background worker has to be told about the new queue,
|
||||
or zips will never finish and nothing will say why. Edit
|
||||
`/etc/systemd/system/projectsend-worker.service` so the `ExecStart` line reads
|
||||
`queue:work --queue=default,zips …`, then `sudo systemctl daemon-reload && sudo systemctl restart
|
||||
projectsend-worker`. Docker installations need no change. See INSTALL.md for the two-worker setup
|
||||
if you would rather keep the two kinds of work apart.
|
||||
**Manual installs:** your background worker has to be told about the new queue, or zips will never
|
||||
finish and nothing will say why. `update.sh` spots this and offers to fix the worker service for
|
||||
you, keeping a copy of the old one — so for most people there is nothing to do but say yes. If you
|
||||
update by hand, or your worker already names its own queues (the updater will say so rather than
|
||||
edit a deliberate arrangement), add `zips` to its `--queue` list and reload systemd. Docker
|
||||
installations need no change. See INSTALL.md for the two-worker setup if you would rather keep the
|
||||
two kinds of work apart.
|
||||
|
||||
### Fixed
|
||||
|
||||
|
||||
@@ -316,6 +316,69 @@ detect_services() {
|
||||
return 0
|
||||
}
|
||||
|
||||
# The worker unit predates the zips queue, and a worker that is not
|
||||
# watching it finishes no zip downloads while cheerfully sending every
|
||||
# email — with nothing in any log to say why. That is the worst shape a
|
||||
# regression can take, so the updater repairs the unit rather than
|
||||
# leaving a note in a changelog nobody reads on a server.
|
||||
#
|
||||
# Only the case that is unambiguous: a command with no --queue at all,
|
||||
# which consumes `default` and nothing else. A unit that already names
|
||||
# queues is somebody's deliberate arrangement — possibly with a second
|
||||
# worker for zips — so that one is described, not rewritten.
|
||||
ensure_worker_watches_zips() {
|
||||
[[ "${SYSTEMD:-0}" == "1" && -n "${WORKER_SERVICE:-}" ]] || return 0
|
||||
|
||||
local unit_file exec_line
|
||||
unit_file="$(systemctl show -p FragmentPath --value "$WORKER_SERVICE" 2>/dev/null || true)"
|
||||
|
||||
[[ -n "$unit_file" && -w "$unit_file" ]] || return 0
|
||||
|
||||
exec_line="$(sed -n 's/^ExecStart=//p' "$unit_file" | head -n 1)"
|
||||
|
||||
case "$exec_line" in
|
||||
*queue:work*) ;;
|
||||
*) return 0 ;;
|
||||
esac
|
||||
|
||||
if [[ "$exec_line" == *"--queue="* ]]; then
|
||||
case "$exec_line" in
|
||||
*zips*) return 0 ;;
|
||||
*)
|
||||
warn "$WORKER_SERVICE names its own queues and does not include 'zips'."
|
||||
warn "Zip downloads will never finish unless some worker watches that queue."
|
||||
warn "Add 'zips' to its --queue list, or run a second worker with --queue=zips."
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
say "Your background worker predates the zips queue"
|
||||
note "Building a zip download runs on its own queue now. $WORKER_SERVICE watches"
|
||||
note "'default' only, so zips would never finish and nothing would say why."
|
||||
note "Change: queue:work -> queue:work --queue=default,zips"
|
||||
|
||||
if ! ask "Update $unit_file? [Y/n]" "y"; then
|
||||
warn "Left alone. Zip downloads will not finish until a worker watches the zips queue."
|
||||
|
||||
return 0
|
||||
fi
|
||||
|
||||
cp -p "$unit_file" "$unit_file.projectsend-bak" 2>/dev/null || true
|
||||
|
||||
# Anchored on the literal command so a unit with other arguments keeps
|
||||
# them, and matched once: a Type=notify unit can carry several
|
||||
# ExecStart lines and only the first is this worker.
|
||||
if sed -i '0,/^ExecStart=/{s|\(^ExecStart=.*queue:work\)|\1 --queue=default,zips|}' "$unit_file"; then
|
||||
systemctl daemon-reload || warn "Could not reload systemd. Run: systemctl daemon-reload"
|
||||
note "Updated. A copy of the old unit is at $unit_file.projectsend-bak"
|
||||
else
|
||||
warn "Could not edit $unit_file. Add --queue=default,zips to its ExecStart line yourself."
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
env_value() {
|
||||
local raw
|
||||
raw="$(first_line "$(sed -n "s/^$1=//p" "$INSTALL_DIR/.env" 2>/dev/null || true)")"
|
||||
@@ -612,6 +675,10 @@ Then reload PHP-FPM, and bring the site back with: php artisan up"
|
||||
|| warn "Could not reload $FPM_SERVICE. Do it yourself, or PHP keeps serving the old code."
|
||||
|
||||
if [[ -n "${WORKER_SERVICE:-}" ]]; then
|
||||
# Before the restart, so the worker comes back on the command
|
||||
# it is going to keep rather than needing a second bounce.
|
||||
ensure_worker_watches_zips
|
||||
|
||||
say "Restarting $WORKER_SERVICE"
|
||||
systemctl restart "$WORKER_SERVICE" || warn "Could not restart $WORKER_SERVICE."
|
||||
fi
|
||||
|
||||
Reference in New Issue
Block a user