3 # Default to an uncommon flockerr because we need to
4 # differentiate from cmd error to avoid bogus retries.
5 # flock's default of 1 would lead to frequent misfires
9 lockdir
=${FLOCK_MULTI_DIR:-"/mnt/cluster/lock"}
10 lockconfdir
=${FLOCK_MULTI_CONF_DIR:-"/mnt/cluster/conf/lock"}
15 echo " flock_multi [-h] [-v] [-E 200] [-s 20] [-w 60m ] heavy 4 heavyscript"
17 echo " -w accepts m and h suffixes "
21 if [ -n "${timeout}" ]; then
22 if [ $
(date +%s
) -gt $timeout ]; then
23 echo "flock_multi timeout" >&2
30 # exit 0 if it's a number
31 echo $1 |
grep -qE '^[[:digit:]]+$'
47 -E|
--conflict-exit-code)
63 echo >&2 "ERROR: Unknown option $1"
73 if [ "$#" -lt 3 ]; then
81 if ! is_number
"${sleeptime}"; then
82 echo "Bad sleptime - should be a number, in seconds" >&2
86 if ! is_number
"${flockerr}"; then
87 echo "Bad conflict exit conflict-exit-code - should be a number" >&2
91 if [ -n "${timeout}" ]; then
92 # expand timeout suffixes
93 if [[ 'm' = "${timeout:${#timeout}-1:1}" ]]; then
94 timeout
=$
(( ${timeout:0:${#timeout}-1} * 60 ))
96 if [[ 'h' = "${timeout:${#timeout}-1:1}" ]]; then
97 timeout
=$
(( ${timeout:0:${#timeout}-1} * 3600 ))
99 if ! is_number
"${timeout}"; then
100 echo "Bad timeout - should be a number, with optional 'm' and 'h' suffixes" >&2
103 # translate timeout to a timeout target time
104 timeout
=$
[ $
(date +%s
) + ${timeout} ]
107 if ! is_number
$locknr ; then
108 echo "Bad default concurrency parameter" >&2
112 lockfile
="$lockdir/$lockname"
114 # Get the value from file, if none, default to 4
115 if [ -f $lockconfdir/$lockname ]; then
116 locknr_tmp
=$
(<${lockconfdir}/${lockname})
117 # tolerate empty file - but barf on bad value
118 if [ -n "${locknr_tmp}" ]; then
119 if ! is_number
$locknr_tmp ; then
120 echo "Bad concurrency parameter in ${lockconfdir}/${lockname}" >&2
126 if [ "${verbose}" = 'y' ]; then
127 echo Using
$locknr locks
130 ## Is there a benefit to this?
131 ## maybe the subshell pid is good enough
132 ## after all, we'll use this to kill it...
136 for trylock
in $
(seq 1 $locknr |
sort --random-sort); do
138 if ! flock
-E $flockerr --nb 200; then
141 if [ "${verbose}" = 'y' ]; then
142 echo Got
${lockfile}.
${trylock}
144 echo "$(hostname) PID: $parent_pid epoch: $(date +%s) $(date -u)" >&200
149 # cleanup - we use the filepath instead of the FD to truncate
150 echo >${lockfile}.
${trylock}
153 ) 200>${lockfile}.
${trylock}
156 if [ $res -ne $flockerr ]; then
159 if [ "${verbose}" = 'y' ]; then
160 echo Bounced
at ${lockfile}.
${trylock}
167 if [ $sleeptime -gt 20 ]; then
168 actual_sleeptime
=$
[ $sleeptime + ($RANDOM % ( $sleeptime / 10 ) - ( $sleeptime / 20) ) ]
170 actual_sleeptime
=$sleeptime
172 if [ "${verbose}" = 'y' ]; then
173 echo Waiting
$actual_sleeptime
175 sleep $actual_sleeptime