#!/bin/bash

trap do_cleanup EXIT 2 3 15

PIDS=""
START=`date +%s`
BASE_DIR="/root/nfs_tests"
export STUFF_DIR="$BASE_DIR/stuff"
export LOGFILE="/root/nfs_log.txt"

do_kill_and_cleanup ()
{
	pid=$1
	kill -9 $pid && echo "+$pid+"
	rm -rf $STUFF_DIR/stuff_$pid
}

do_cleanup ()
{
	echo "Killing Syncer $SYNC_PID" && kill -9 $SYNC_PID

	echo -n "Killing children |$PIDS| ... "
	for pid in $PIDS
	do
		kill -9 $pid && echo $PID
	done
	STOP=`date +%s`
	echo  "+ Writers: $WRITERS  ~SZ:$WRSZ  -- Run for secs: $((STOP-START))  Sync every: $SYNCER_TM"

	trap - EXIT

	exit 0
}

do_run_syncer ()
{
	slept=$1
	/bin/bash -c "while true;do sleep $slept && sync;done" &
	SYNC_PID=$!
	echo "Syncer running PID:$SYNC_PID ... every $slept secs..."
}

do_spawn_writer ()
{
	# Base size ... it will be randomly increased by a <4kb quantity
	wsz=$1
	## takes 2.5 secs to write and sync 8MB
	/bin/bash -c 'while true;do BS=$((${0} + $RANDOM / 10)) ; OF=$STUFF_DIR/stuff_${BASHPID} ; dd if=/dev/urandom of=$OF bs=$BS count=1 2>/dev/null && sleep 0.3;done' $wsz &
	wpid=$!
	PIDS="$PIDS $wpid"
	echo "-> Started writer PID $wpid to file $STUFF_DIR/stuff_$wpid"
}

do_thundering_herd ()
{
	wnum=$1
	wsz=$2

	echo "Spawning $wnum writers..."

	for i in `seq 0 $wnum`
	do
		do_spawn_writer $wsz
		sleep 0.01
	done
}


do_idle ()
{
	wsz=$1
	victims=$2

	echo -n "===>>> JUST Idling...killing periodically $victims writers..."
	while true
	do
		cnt=0
		newpids=""
		sleep 10 && echo -n "."
		for pid in $PIDS
		do
			if [ $cnt -lt $victims ]
			then
				do_kill_and_cleanup $pid
				cnt=$((cnt+1))
			else
				newpids="$newpids $pid"
			fi
		done
		## copy survivors
		PIDS=$newpids
		## .. and respawn
		for i in `seq 0 $((cnt-1))`
		do
			do_spawn_writer $wsz
		done
	done
}

## main
WRITERS=100
WRSZ=8192
SYNCER_TM=1

echo "Cleaning up $STUFF_DIR" && rm -rf "$STUFF_DIR" && mkdir -p $STUFF_DIR
sync

while getopts "w:s:t:" option
do
	case $option in
		"w")
			WRITERS=$OPTARG
			;;
		"s")
			WRSZ=$OPTARG
			;;
		"t")
			SYNCER_TM=$OPTARG
			;;
		*)
			echo "Usage $0 -w <num_writers> -s <wr_size> -t <syncer_period>"
			exit 1
			;;
	esac
done

do_run_syncer $SYNCER_TM && sleep 1

do_thundering_herd $WRITERS $WRSZ

do_idle $WRSZ $((WRITERS / 10))

