#!/usr/bin/env bash # Starts three replicas of the application against one database, lets the schedule tick, and # tallies who ran the job. # # scripts/three-replicas.sh unlocked # no @EnableSchedulerLock: every replica runs it # scripts/three-replicas.sh locked # ShedLock with usingDbTime() # scripts/three-replicas.sh appclock 40 # ShedLock without usingDbTime(), replica-3 40s fast # # Environment: # RUN_FOR seconds to let the schedule tick (default 30; three JVMs need ~10s to start) # JOB_DURATION ISO-8601 duration the job sleeps for (default PT0.2S) set -euo pipefail cd "$(dirname "$0")/.." PROFILE="${1:-unlocked}" SKEW_SECONDS="${2:-0}" RUN_FOR="${RUN_FOR:-30}" JOB_DURATION="${JOB_DURATION:-PT0.2S}" JAR=target/scheduling-1.0.jar PSQL=(scripts/postgres.sh psql) [ -f "$JAR" ] || mvn -B -q -DskipTests package "${PSQL[@]}" -q -c "delete from job_execution" -c "delete from shedlock" >/dev/null 2>&1 || true pids=() for n in 1 2 3; do skew=() if [ "$SKEW_SECONDS" != "0" ] && [ "$n" = "3" ]; then skew=(-Dclock.skew="PT${SKEW_SECONDS}S") fi java -Dspring.profiles.active="$PROFILE" -DINSTANCE_ID="replica-$n" \ -Djob.duration="$JOB_DURATION" "${skew[@]}" \ -jar "$JAR" > "target/replica-$n.log" 2>&1 & pids+=($!) done sleep "$RUN_FOR" for p in "${pids[@]}"; do kill "$p" 2>/dev/null || true; done wait 2>/dev/null || true echo "profile=$PROFILE replicas=3 run-for=${RUN_FOR}s job rate=3s job duration=$JOB_DURATION replica-3 clock skew=${SKEW_SECONDS}s" echo echo "-- every execution, in order --" "${PSQL[@]}" -c "select instance_id, to_char(started_at,'HH24:MI:SS.MS') as started_at from job_execution order by started_at" echo "-- executions per replica --" "${PSQL[@]}" -c "select instance_id, count(*) from job_execution group by instance_id order by instance_id" OVERLAP="b.id > a.id and b.instance_id <> a.instance_id and b.started_at < a.started_at + interval '$JOB_DURATION'" echo "-- pairs of executions that overlapped (a second replica started while the first was still working) --" "${PSQL[@]}" -c "select count(*) as overlapping_pairs from job_execution a join job_execution b on $OVERLAP" "${PSQL[@]}" -c "select a.instance_id as first, to_char(a.started_at, 'HH24:MI:SS.MS') as first_at, b.instance_id as second, to_char(b.started_at, 'HH24:MI:SS.MS') as second_at from job_execution a join job_execution b on $OVERLAP order by a.started_at limit 6" echo "-- the lock row --" "${PSQL[@]}" -c "select name, locked_by, to_char(locked_at,'HH24:MI:SS.MS') as locked_at, to_char(lock_until,'HH24:MI:SS.MS') as lock_until from shedlock"