diff --git a/pool b/pool index 0200962..e9bc45e 100755 --- a/pool +++ b/pool @@ -7,59 +7,116 @@ ROOT=$(dirname `realpath $0`); # (2) Check argc -test $# -lt 2 && echo -e "error: too fewarguments\n\n\e[1mUSAGE\e[0m\n\tpool \n\n\e[1mARGUMENTS\e[0m\n\t\tThe identifier of the pool (client must match it)\n\t\tTo port to listen to\n" && exit 1; +test $# -lt 2 && echo -e "error: too fewarguments\n\n\e[1mUSAGE\e[0m\n\tpool \n\n\e[1mARGUMENTS\e[0m\n\t\tThe key of the pool (client must match it)\n\t\tTo port to listen to\n" && exit 1; # (3) Check @PORT range # -MIN_PORT=49152; -MAX_PORT=65535; +MIN_PORT=1024; +MAX_PORT=49151; test "$2" -gt "$MAX_PORT" -o "$2" -lt "$MIN_PORT" && echo "error: must be between $MIN_PORT and $MAX_PORT" && exit 1; # (4) Set argument explicit names # -POOL_ID="$1"; -POOL_PT="$2"; +POOL_KEY="$1"; +POOL_PORT="$2"; + +# (5) init logger variables # +declare -A INPUT_PID; # will contain each bind-input pid -# (2) Launch pool listener + + +# (2) Set exit management #--------------------------------------------------------# -# (1) Start the script in background -listfail=0; +# (1) On-Exit routine # +on_exit(){ + echo "killing 'bind-input' sub processes"; + + for logger_name in "${!INPUT_PID[@]}"; do + + # kill each logger input + kill -9 ${INPUT_PID[$logger_name]} 2>/dev/null; + $INPUT_PID[$logger_name]=""; + + done; + + echo "killing 'pool' input listener"; + kill -9 $POOL_PID 2>/dev/null; + + echo "killing 'pool' loop"; + kill -9 $LOOP_PID 2>/dev/null; + +} + +trap "on_exit;" INT KILL; + + + + + +# (3) Launch pool listener +#--------------------------------------------------------# +# (1) Bind-input # +echo "(.) listen $POOL_PORT"; +$ROOT/bind-input pool $POOL_PORT& +POOL_PID=$?; + + + +# (4) Launch pool manager +#--------------------------------------------------------# # infinite listener -while true; do +while sleep 1; do - # Listen on port @2 - echo "(.) listen $POOL_PT"; - MSG=`nc -lp $POOL_PT`; + # Listen on port @POOL_PORT + MSG=`$ROOT/read pool`; - # Do nothing if empty msg + # Do nothing if empty msg or invalid format test -z "$MSG" && continue; + echo -n "$MSG" | grep -vP '^([^:]+):([^:]+):([^:]+):([^:]+)$' >/dev/null && echo ' /!\\ invalid format' && continue; # Extract ID - PORT - CLI_ID="`echo -ne \"$MSG\" | sed 's/^\(.\+\):\(.\+\)$/\1/'`"; - CLI_PT="`echo -ne \"$MSG\" | sed 's/^\(.\+\):\(.\+\)$/\2/'`"; + KEY="`echo -ne \"$MSG\" | sed 's/^\(.\+\):\(.\+\):\(.\+\):\(.\+\)$/\1/'`"; + LOGGER_NAME="`echo -ne \"$MSG\" | sed 's/^\(.\+\):\(.\+\):\(.\+\):\(.\+\)$/\2/'`"; + LOGGER_HOST="`echo -ne \"$MSG\" | sed 's/^\(.\+\):\(.\+\):\(.\+\):\(.\+\)$/\3/'`"; + LOGGER_PORT="`echo -ne \"$MSG\" | sed 's/^\(.\+\):\(.\+\):\(.\+\):\(.\+\)$/\4/'`"; # if ID does not match - test "$CLI_ID" != "$POOL_ID" && echo " /!\\ wrong id" && continue; + test "$KEY" != "$POOL_KEY" && echo ' /!\\ wrong id' && continue; # create new listening socket - echo " [x] creating socket"; + echo " (.) binding input for logger@$LOGGER_NAME ($LOGGER_HOST:$LOGGER_PORT)"; # Find an available port PORT="$MIN_PORT"; while true; do - test "$PORT" = "$POOL_PT" && PORT="`expr $PORT + 1`" && continue; + # ignore pool port + test "$PORT" = "$POOL_PORT" && PORT="`expr $PORT + 1`" && continue; - echo -n " ?? port $PORT -> "; - ss -tl4 "( sport = :$PORT )" | grep "$PORT" >/dev/null 2>&1 || (echo "free"; exit 1) || break; + # if port not in use -> use it + ss -tl4 "( sport = :$PORT )" | grep "$PORT" >/dev/null 2>&1 || break; - echo "used"; + # else try next port (+1) PORT="`expr $PORT + 1`"; done; - echo " > listen $PORT"; + # Bind-input for the logger at the free port found + $ROOT/bind-input $LOGGER_NAME $PORT& -done; + # if already an input for this logger -> kill it + test ! -z "${INPUT_PID[$LOGGER_NAME]}" && kill -9 ${INPUT_PID[$LOGGER_NAME]}; + + # Store bind-input PID + INPUT_PID[LOGGER_NAME]=$!; + + # Notify that input is active to MASTER + bash -c "exec 4<>/dev/tcp/$LOGGER_HOST/$LOGGER_PORT; echo -n \"$PORT\" >&4;"; + +done& + +LOOP_PID=$!; + +wait $LOOP_PID;