bin bash set -bm MAXTRIES MAXP 32 cmds for in 512 do sl RANDOM 10 eval

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
#!/bin/bash
set -bm
MAXTRIES=3
MAXP=32
cmds=( )
for i in {1..512}; do
sl=$((RANDOM % 10 + 3))
eval "function randsleep${sl}() { (set -x; sleep $(( $sl + RANDOM % 5 - 2 ));); };"
cmds+=( randsleep${sl} )
done
function runpartsp() {
local cmdqueue=( )
local pids=( )
local start_ts=( )
local tries=( )
curts=$(date +%s)
success_count=0
failed_count=0
function queue_command() {
local cmd="${1}"
local tries_made=${2}
if [ ${tries_made} -lt ${MAXTRIES} ]; then
local next_try=$(( ${2} + 1 ))
cmdqueue+=( "${1}" )
tries+=( ${next_try} )
start_ts+=( 0 )
printf "I [%d] attempt %d/%d queued #%d: '%s'\n" ${curts} ${next_try} ${MAXTRIES} ${#cmdqueue[@]} "${cmd}" >&2
else
printf "W [%d] tries exhaused: '%s'\n" ${curts} "${cmd}" >&2
(( ++failed_count ))
fi
}
for cmd in "${cmds[@]}"; do
queue_command "${cmd}" 0
done
curcmd=0
running_count=0
slpid=0
while [ ${running_count} -gt 0 -o ${curcmd} -lt ${#cmdqueue[@]} ]; do
curts=$(date +%s)
printf "I [%d] running jobs: %d, job queue: %d/%d\n" ${curts} ${running_count} ${curcmd} ${#cmdqueue[@]} >&2
if [ ${running_count} -lt ${MAXP} -a ${curcmd} -lt ${#cmdqueue[@]} ]; then
printf "I [%d] running: '%s'\n" ${curts} "${cmdqueue[$curcmd]}" >&2
"${cmdqueue[$curcmd]}" &
pid=$!
pids+=($pid)
printf "I [%d] [%d] process started\n" ${curts} ${pid} >&2
start_ts[$curcmd]=${curts}
(( ++curcmd ))
(( ++running_count ))
else
sleep 999999 &
slpid=$!
trap "trap -- \"\" SIGCHLD; kill $slpid;" SIGCHLD
wait $slpid 2>/dev/null
trap -- "" SIGCHLD
curts=$(date +%s)
for ((idx=0;idx<${#pids[@]};++idx)); do
pid=${pids[$idx]}
[ $pid -ne 0 ] || continue
error="nan"
if ! kill -0 ${pid} 2>/dev/null; then
error=0
wait ${pid} 2>/dev/null || error=$?
fi
if [ "$error" != "nan" ]; then
printf "I [%d] [%d] finished with status %d\n" ${curts} ${pid} ${error}
pids[$idx]=0
(( running_count-- ))
if [ "$error" = 0 ]; then
(( ++success_count ))
else
queue_command "${cmdqueue[$idx]}" ${tries[$idx]}
fi
fi
done
fi
done
printf "I [%d] All done: success %d, failed %d\n" ${curts} ${success_count} ${failed_count}
}
runpartsp