#!/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() { file="${POOL}/proc_${procid}" echo cmd=\"${PROC_CMD}\" > "$file" echo "procpid=${procpid}" >> "$file" echo "procid=${procid}" >> "$file" echo "startat=${startat}" >> "$file" } setp() { file="${POOL}/proc_${procid}" echo $1=$2 >> "$file" } getp() { file="${POOL}/proc_${procid}" source "$file" echo "${!1}" } 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() { 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" } # Ensure pool exists [ ! "$CMD" == "create" ] && [ ! "$CMD" == "ls" ] && [ ! -d "$POOL" ] && abort "Pool $POOL_ID not found" # Launch command case "$CMD" in "create") create $1 ;; "remove") remove ;; "run") run ;; "cat") procid=$1 refresh [ $procid -gt $lastprocid ] && abort "Processus $procid not found" cat_output ;; "ls-output") list_output ;; "ls") list_pool ;; "wait") wait_pool ;; "remove-force") remove_force ;; "setp") procid=$1 setp $2 $3 ;; "getp") procid=$1 getp $2 ;; *) abort "Command $CMD unknown" esac