Ctrl K
ComunidadGuías…

dev-services.sh

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
#!/bin/sh
# Starts and stops the KiloCenter development services that start-dev.sh runs.
#
#   dev-services.sh start NAME   start one service and print its PID
#   dev-services.sh stop         stop every service this checkout started
#   dev-services.sh log NAME     print the path of the service's log
#
# NAME is kc-core, kc-identity, kc-gateway or kc-web. A service runs through
# exec, so its pid file holds the service's own PID. Stop ends the process a
# pid file names and every process it started, and only while that process
# still runs the service's command: a stale pid file never kills anything.

KC_ROOT=$(CDPATH='' cd -- "$(dirname -- "$0")" && pwd)
KC_PID_DIR="$KC_ROOT/../logs/pids"
KC_LOG_DIR="$KC_ROOT/../logs/runtime"
# Seconds a service gets to exit after SIGTERM before it is killed.
KC_STOP_TIMEOUT="${KC_STOP_TIMEOUT:-10}"
# The web server and the gateway stop before KC-Identity and KC-Core, so the
# gateway cannot reconnect to them while they shut down; a reconnecting
# gateway leaves port 50052 in TIME_WAIT.
KC_STOP_ORDER="kc-web kc-gateway kc-identity kc-core"

usage() {
    echo "usage: $0 start NAME | stop | log NAME  (NAME: kc-core, kc-identity, kc-gateway, kc-web)" >&2
    exit 2
}

service_dir() {
    case "$1" in
    kc-core) echo "$KC_ROOT/KC-Core" ;;
    kc-identity) echo "$KC_ROOT/KC-Identity" ;;
    kc-gateway) echo "$KC_ROOT/KC-Gateway" ;;
    kc-web) echo "$KC_ROOT/KC-Web" ;;
    *) return 1 ;;
    esac
}

# service_command is the command line a service runs as, as ps reports it.
service_command() {
    case "$1" in
    kc-core) echo "./kilocenter -config config.yaml" ;;
    kc-identity) echo "./identity -config config.yaml" ;;
    kc-gateway) echo "./gateway -config config.yaml" ;;
    kc-web) echo "bun run dev" ;;
    *) return 1 ;;
    esac
}

start_service() {
    dir=$(service_dir "$1") || usage
    mkdir -p "$KC_PID_DIR" "$KC_LOG_DIR"
    # The command is split into its words on purpose.
    (cd "$dir" && exec $(service_command "$1")) >"$KC_LOG_DIR/$1.log" 2>&1 &
    echo "$!" >"$KC_PID_DIR/$1.pid"
    echo "$!"
}

# descendants prints the PID of every process below the process $1.
descendants() {
    ps -A -o pid= -o ppid= | awk -v root="$1" '
        { kids[$2] = kids[$2] " " $1 }
        END {
            n = split(kids[root], stack, " ")
            while (n > 0) {
                pid = stack[n--]
                print pid
                m = split(kids[pid], more, " ")
                for (i = 1; i <= m; i++) stack[++n] = more[i]
            }
        }'
}

any_alive() {
    for pid in "$@"; do
        kill -0 "$pid" 2>/dev/null && return 0
    done
    return 1
}

# signal_and_wait sends the signal $1 to the processes that follow and waits
# up to KC_STOP_TIMEOUT seconds for them to exit; it fails if one outlives it.
signal_and_wait() {
    signal=$1
    shift
    kill -s "$signal" "$@" 2>/dev/null
    waited=0
    while any_alive "$@"; do
        [ "$waited" -ge "$KC_STOP_TIMEOUT" ] && return 1
        sleep 1
        waited=$((waited + 1))
    done
}

stop_service() {
    name=$1
    pidfile="$KC_PID_DIR/$name.pid"
    [ -f "$pidfile" ] || return 0
    pid=$(cat "$pidfile")
    rm -f "$pidfile"
    if [ "$(ps -o args= -p "$pid" 2>/dev/null)" != "$(service_command "$name")" ]; then
        echo "$name was not running"
        return 0
    fi
    echo "Stopping $name (PID $pid)..."
    set -- "$pid" $(descendants "$pid")
    signal_and_wait TERM "$@" || signal_and_wait KILL "$@"
    echo "$name stopped"
}

case "$1" in
start)
    [ $# -eq 2 ] || usage
    start_service "$2"
    ;;
stop)
    [ $# -eq 1 ] || usage
    for name in $KC_STOP_ORDER; do
        stop_service "$name"
    done
    ;;
log)
    [ $# -eq 2 ] && service_dir "$2" >/dev/null || usage
    echo "$KC_LOG_DIR/$2.log"
    ;;
*) usage ;;
esac