-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathredis-pool
executable file
·69 lines (59 loc) · 2.43 KB
/
redis-pool
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
#!/usr/bin/env bash
# Brief: Create and keepalive N connections to Redis and bind them to a Unix domain or TCP socket
# Usage: ./redis-pool [options] <TCP-port-number | path-to-Unix-socket>
# Options:
# -n <number of connections>
# -h <host>
# -p <port>
# -a <passwd>
# -t <idle timeout s>
# -d <database no.>
# The given local socket simply serves as a proxy for the remote Redis server; i.e. RESP responses are served over the socket;
# The user still needs to parse the responses with `redis_read` or `redis_rep` from the `redis.bash` library.
# The socket transforms trailing LF to CRLF so user doesn't need to worry about that.
# Example: Pipelining 2 commands
# echo -e "command 1\nCommand 2" | nc -N localhost <port number> | redis_rep -n2
. "${BASH_SOURCE%/*}/redis.bash"
while getopts ':h:p:a:t:d:n:' opt;do
case "${opt}" in
h) REDIS_HOST="${OPTARG}";;
p) REDIS_PORT="${OPTARG}";;
a) REDIS_AUTH="${OPTARG}";;
t) REDIS_TIMEOUT="${OPTARG}";;
d) REDIS_DB="${OPTARG}";;
n) num_conn="${OPTARG}";;
*) echo "Usage: ${0} [-h <host>] [-p <port>] [-a <passwd>] [-t <idle timeout s>] [-d <database no.>] [-n <no. of connections>] <socket's file-path or localhost port number>" >&2; exit;;
esac
done
socket="${!OPTIND}"
[[ "${socket}" ]] || { echo "Pass a Unix-socket file-path or localhost TCP port number as parameter. For more help, use: ${0} -h" >&2; exit;}
if [[ "${socket}" =~ ^[0-9]*$ ]]; then
unix_sock=false
socketaddr="TCP4-LISTEN:${socket}"
else
unix_sock=true
socketaddr="UNIX-LISTEN:${socket}"
fi
num_conn="${num_conn:-1}"
single_conn(){
local usock="${1}"
trap "redis_disconnect; rm -f ${usock}" return
trap '' HUP
trap 'return' TERM QUIT INT
redis_connect || return "$?"
while :; do
redis_exec 'PING' >/dev/null || redis_connect || continue # Tests connection to remote Redis server, reconnects if necessary
socat -W "${REDIS_LOCK}" UNIX-L:"${usock}",crlf FD:"${REDIS_FD}"
done
} &>/dev/null
trap "${unix_sock} && rm -f ${socket}; pkill -s $$" INT QUIT TERM HUP exit
for i in $(seq ${num_conn}); do
usock="socket-${i}"
rm -f "${usock}"
single_conn "${usock}" &
done
sleep 0.1 # Giving time to single_conn in bg to create the sockets
socat "${socketaddr}",reuseaddr,fork \
SYSTEM:'until for s in socket-*;do nc -U ${s} && break; done; do sleep 0;done' &>/dev/null
# Note the `until` loop above. It makes sure every request is fed to the server even if there is an initial wait
exit