Last active
March 19, 2016 16:25
-
-
Save piersy/e6f6c8b907437a66726e to your computer and use it in GitHub Desktop.
Throttling asynchronous processes in bash
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
#Fail fast on errors | |
set -euo pipefail | |
# Arguments | |
# $1 -> throttlerName | |
# Initializes a throttler of the given name | |
initThrottler(){ | |
rm $1 2>/dev/null|| true | |
mkfifo $1 | |
exec 3<> $1 | |
} | |
# Arguments | |
# $1 -> limit | |
# $2 -> throttlerName | |
# Called before running any processes | |
# Will wait while the current number of running processes | |
# exceed the given limit | |
throttle(){ | |
local limit=$1 | |
local throttlerName=$2 | |
#We generate a counter name here so that | |
#Different throttler's counts dont interact with | |
#each other. This makes the access of the variable | |
#a little tricky. | |
local counterName=${throttlerName}Counter | |
if [[ -z ${!counterName:-} ]]; then | |
eval "$counterName=0" | |
fi | |
eval "$counterName=$((${counterName}+1))" | |
if [[ ${!counterName} > $limit ]]; then | |
while read line < $throttlerName; do | |
echo $line | |
eval "$counterName=$((${counterName}-1))" | |
if [[ ${!counterName} -le $limit ]]; then | |
break | |
fi | |
done | |
fi | |
} | |
#Usage below | |
randomLongProcess(){ | |
sleep $((RANDOM % 10)) | |
echo fin > $throttlerName | |
} | |
throttlerName=testThrottler | |
initThrottler $throttlerName | |
for x in {1..10}; do | |
#Call throttle first | |
throttle 3 $throttlerName | |
#echo Update | |
echo Process number $x | |
#Start background process | |
randomLongProcess & | |
done | |
wait |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This was useful to me for multithreading builds while not totally overloading my machine.