#!/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=1 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" } write_process() { 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 write_process # 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