pool/pool.sh
Loic Guegan 25e3092887 Debug
2021-08-22 09:00:50 +02:00

220 lines
4.1 KiB
Bash
Executable file

#!/usr/bin/env bash
set -e
# Fetch arguments
CMD=$1
if [ $# -gt 1 ]
then
POOL_ID=$2
shift 2
PROC_CMD=$@
fi
# Config: feel free to change at your own risks
TMPDIR=/tmp
POOL_FORMAT="pool_${POOL_ID}"
POOL="${TMPDIR}/${POOL_FORMAT}/"
POOL_STATUS="${POOL}/status"
REFRESH_EVERY=2
abort() {
echo $@
exit 1
}
write_status() {
echo "maxproc=${maxproc}" > "$POOL_STATUS"
echo "nproc=${nproc}" >> "$POOL_STATUS"
echo "procs=\"${procs}\"" >> "$POOL_STATUS"
echo "lastprocid=$lastprocid" >> "$POOL_STATUS"
}
create_properties() {
local file="${POOL}/proc_${procid}"
echo cmd=\"${PROC_CMD}\" > "$file"
echo "procpid=${procpid}" >> "$file"
echo "procid=${procid}" >> "$file"
echo "startat=${startat}" >> "$file"
}
setp() {
local file="${POOL}/proc_${procid}"
sed -i "/${1}=/d" "$file"
echo $1=\"$2\" >> "$file"
}
getp() {
local file="${POOL}/proc_${procid}"
value=$(grep "^$1=" "$file"||:)
[ -z "$value" ] && echo "Property $1 not found for process ${procid}" || { echo "$value" | sed "s/^$1=//" | xargs echo; }
}
create() {
[ -d "$POOL" ] && abort "Pool \"$POOL\" already exists" || :
mkdir -p "$POOL"
# Write pool status
maxproc=$1
nproc=0
procs=""
lastprocid=0
write_status
}
remove() {
refresh # Refresh process status and load status
[ $nproc -gt 0 ] && abort "Processes are still running in the pool!" || :
rm -rf "$POOL"
}
refresh() {
source "$POOL_STATUS"
procs_new=""
for proc in $procs
do
if kill -0 $proc &>/dev/null
then
[ -z "$procs_new" ] && procs_new="$proc" || procs_new="$procs_new $proc"
fi
done
procs=$procs_new
nproc=$(echo "$procs"|wc -w)
write_status
}
run() {
refresh
# Wait for room in the pool
while [ $nproc -ge $maxproc ]
do
sleep $REFRESH_EVERY
refresh
done
# Create new process
nproc=$(( nproc + 1 ))
procid=$(( lastprocid + 1 ))
lastprocid=$procid
startat=$(date +"%s")
$PROC_CMD &> "$POOL/out_$procid" &
procpid=$!
[ -z "$procs" ] && procs="$procpid" || procs="$procs $procpid"
write_status # Update status
create_properties # Create process properties
echo $procid # Return process id
}
cat_output() {
local file="${POOL}/out_${procid}"
cat "$file"
}
list_pool() {
find "${TMPDIR}" -name "${POOL_FORMAT}*" -exec basename {} \; 2>/dev/null | sed "s/${POOL_FORMAT}//g"
}
wait_pool() {
refresh
while [ $nproc -gt 0 ]
do
sleep $REFRESH_EVERY
refresh
done
}
list_output() {
refresh
find "${POOL}" -name "out_*"
}
remove_force() {
refresh
for proc in $procs
do
kill -9 $proc
done
rm -rf "$POOL"
}
check_pool() {
if [ ! -d "$POOL" ]; then abort "Pool ${POOL_ID} not found"; fi
if [ ! -f "$POOL_STATUS" ]; then abort "Pool ${POOL_ID} corrupted: status file not found"; fi
if [ $# -gt 0 ]
then
[ ! -f "${POOL}/proc_${1}" ] && echo abort "Process $1 does not exists in pool ${POOL_ID}" || :
fi
}
pause() {
refresh
for proc in $procs
do
kill -STOP $proc
done
}
resume() {
refresh
for proc in $procs
do
kill -CONT $proc
done
}
# Launch command
case "$CMD" in
"create")
create $1
;;
"remove")
check_pool
remove
;;
"run")
check_pool
run
;;
"cat")
check_pool $1
procid=$1
refresh
[ $procid -gt $lastprocid ] && abort "Processus $procid not found" || cat_output
;;
"ls-output")
check_pool
list_output
;;
"ls")
check_pool
list_pool
;;
"wait")
check_pool
wait_pool
;;
"remove-force")
check_pool
remove_force
;;
"setp")
check_pool $1
procid=$1
setp $2 $3
;;
"getp")
check_pool $1
procid=$1
getp $2
;;
"pause")
check_pool
pause
;;
"resume")
check_pool
resume
;;
*)
abort "Command $CMD unknown"
esac