rhailib/start_ws_servers.sh
2025-06-12 05:21:52 +03:00

158 lines
5.1 KiB
Bash
Executable File

#!/bin/bash
# Exit immediately if a command exits with a non-zero status.
# set -e # We will handle errors manually for cleanup
# Instead of set -e, we'll check command statuses and exit if needed after attempting cleanup.
# Default to not force killing processes
FORCE_KILL=false
# Parse command-line options
while getopts "f" opt; do
case ${opt} in
f )
FORCE_KILL=true
;;
\? )
echo "Invalid option: -$OPTARG" 1>&2
exit 1
;;
esac
done
shift $((OPTIND -1))
# Array to store PIDs of background processes
BG_PIDS=()
# Cleanup function
cleanup() {
echo "Caught signal, cleaning up background processes..."
for pid in "${BG_PIDS[@]}"; do
if ps -p "$pid" > /dev/null; then # Check if process exists
echo "Stopping process $pid..."
kill "$pid"
fi
done
# Wait for all background processes to terminate
for pid in "${BG_PIDS[@]}"; do
if ps -p "$pid" > /dev/null; then
wait "$pid" 2>/dev/null # Suppress "No such process" if already gone
fi
done
echo "All background processes stopped."
exit 0 # Exit script after cleanup
}
# Trap SIGINT (Ctrl+C) and SIGTERM
trap cleanup SIGINT SIGTERM
# Define circles and their base port
# The client will need to know these port assignments.
# Circle names should match what's in your mock data for consistency,
# but for the WS server, it's what the server identifies itself as.
# The client will use the lowercase_with_underscores version for the path.
# Define circles and their ports using indexed arrays
CIRCLE_NAMES=(
"OurWorld"
"My Personal Space"
"threefold"
"circles_app"
)
CIRCLE_PORTS=(
"9000"
"9001"
"9002"
"9003"
)
# Add more circles and their ports here if needed, ensuring arrays match
# Build the WebSocket server first
echo "Building circle_server_ws..."
cargo build --package circle_server_ws
if [ $? -ne 0 ]; then echo "Failed to build circle_server_ws"; cleanup; exit 1; fi
echo "Building rhai_worker..."
cargo build --package rhai_worker
if [ $? -ne 0 ]; then echo "Failed to build rhai_worker"; cleanup; exit 1; fi
# Paths to the compiled binaries
WS_SERVER_BINARY="./target/debug/circle_server_ws"
RHAI_WORKER_BINARY="./target/debug/rhai_worker"
if [ ! -f "$WS_SERVER_BINARY" ]; then
echo "Error: WebSocket server binary not found at $WS_SERVER_BINARY after build."
cleanup
exit 1
fi
if [ ! -f "$RHAI_WORKER_BINARY" ]; then
echo "Error: Rhai worker binary not found at $RHAI_WORKER_BINARY after build."
cleanup
exit 1
fi
echo "Starting WebSocket servers..."
for i in "${!CIRCLE_NAMES[@]}"; do
NAME="${CIRCLE_NAMES[i]}"
PORT="${CIRCLE_PORTS[i]}"
if [ "$FORCE_KILL" = true ]; then
echo "Checking if port $PORT is in use (force mode)..."
# lsof -i :<port> -t lists PIDs listening on the port
# The output might be empty or multiple PIDs.
# We'll kill any PID found.
PIDS_ON_PORT=$(lsof -i ":$PORT" -t 2>/dev/null || true) # Suppress lsof error if port not in use, || true ensures command doesn't fail script
if [ -n "$PIDS_ON_PORT" ]; then
for PID_TO_KILL in $PIDS_ON_PORT; do
echo "Port $PORT is in use by PID $PID_TO_KILL. Forcing kill..."
kill -9 "$PID_TO_KILL" # Force kill
# Add a small delay to give the OS time to free the port
sleep 0.5
done
else
echo "Port $PORT is free."
fi
fi
# The circle name passed to the server is the "identity" name.
# The client will still connect to ws://localhost:PORT/ws
echo "Starting server for '$NAME' on port $PORT..."
# Run in background
"$WS_SERVER_BINARY" --port "$PORT" --circle-name "$NAME" &
BG_PIDS+=($!) # Store PID of the last backgrounded process
done
echo "All WebSocket servers launched."
# Prepare circle names for rhai_worker
# It expects names like "OurWorld", "My Personal Space"
# We can directly use the CIRCLE_NAMES array
echo "Starting Rhai worker for circles: ${CIRCLE_NAMES[@]}..."
# Run rhai_worker in the background
# Assuming default Redis URL redis://127.0.0.1/
"$RHAI_WORKER_BINARY" --circles "${CIRCLE_NAMES[@]}" &
BG_PIDS+=($!) # Store PID of the Rhai worker
echo "Rhai worker launched."
echo "All processes launched. Press Ctrl+C to stop all servers and the worker."
# Wait for all background PIDs.
# If any of them exit prematurely, this script will also exit.
# The trap will handle cleanup if Ctrl+C is pressed.
for pid in "${BG_PIDS[@]}"; do
wait "$pid"
# If a process exits with an error, its exit code will be propagated by wait.
# The script will then exit due to `wait` itself exiting with that code.
# The trap should still run on SIGINT/SIGTERM.
# For other signals or unexpected exits, the trap might not run.
# More robust error handling for individual process failures could be added here.
done
# If all processes exited cleanly (e.g., were killed by the trap),
# the script will reach here. The trap's exit 0 will handle this.
# If they exited due to an error, `wait` would have exited the script.
cleanup # Call cleanup if all jobs finished normally (e.g. if they self-terminate)