stopProjectForge.sh| Commit | Message |
|---|---|
ac75fabf3 | Github pages migrated to Asciidoc |
checkStopped() {
pid=$(pgrep -f $PROCESS_IDENTIFIER) # Re-check if process exists
if [[ -z $pid ]]; then # If no PID found
echo "${APP_NAME} $1" # Print success message
exit 0 # Exit immediately
fi
if [[ -n $2 ]]; then # If second arg given (warning mode)
echo "${APP_NAME} $2" # Print warning but continue
fi
}Dual-mode function: checkStopped serves two purposes depending on argument count — with 1 arg it's a "success check" (exits if stopped), with 2 args it's a "status report" (prints and continues).
Variable scope bug: $pid is set inside the function (line 7) but used outside on line 20 — this works because pid isn't declared local, so it leaks to the caller's scope. Fragile — if a second matching process appears between checks, only the first PID gets killed.
site/uploads/ — the Jekyll site's file attachments — an unusual location for operational tooling.procps-ng package — not available on minimal Docker images.
The script identifies the ProjectForge Java process via
pgrep -f "java.*projectforge-application"(pattern matching on the JVM command line), then executes:kill $pidsends SIGTERM (signal 15). The JVM catches this and triggers Spring's@PreDestroylifecycle callbacks — Hibernate flushes caches, connection pools close, Quartz jobs stop, Tomcat shuts down. The script loops 20 times × 3 seconds, checking if the process is gone.kill -9 $pidsends SIGKILL (signal 9) — uncatchable, immediate termination. No cleanup: database connections orphaned, Lucene indexes potentially corrupted, log buffers lost. The script waits 2 seconds and checks again.This two-phase approach prevents the most common production issue: database connection leaks from killed Java processes. The 60-second window is generous — most Spring Boot apps shut down in 5-15 seconds.