229 lines
4.2 KiB
Bash
Executable file
229 lines
4.2 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
|
|
}
|
|
|
|
status() {
|
|
refresh
|
|
cat "${POOL_STATUS}"
|
|
}
|
|
|
|
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
|
|
;;
|
|
"status")
|
|
check_pool
|
|
status
|
|
;;
|
|
*)
|
|
abort "Command $CMD unknown"
|
|
esac
|
|
|