-
Notifications
You must be signed in to change notification settings - Fork 0
/
bash-listener.sh
86 lines (71 loc) · 1.9 KB
/
bash-listener.sh
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
#!/bin/bash
set -uo pipefail
#set -x
### Library ###
function read_messages_forever() (
trap "cleanup" INT
local g_log_name=$1
local g_db_uri=$2
local g_per_message_callback=$3
local g_poll_loop_pid=
local g_psql_input=
local g_psql_output=
# started at the bottom
function run_poll_loop() {
# read existing once
_read_log_entries_from_db
_poll_psql
while read line; do
if echo "${line}" | \
grep -q "Asynchronous notification \"log_${g_log_name}\" received"; then
_read_log_entries_from_db
fi
done < ${g_psql_output}
}
function _read_log_entries_from_db() {
local message=
while true; do
message=$(echo "SELECT read_log_entry('${g_log_name}')" | \
psql --quiet --tuples-only --no-align --no-psqlrc "${g_db_uri}")
if [ "${message}" ]; then
${g_per_message_callback} "${message}"
else
break
fi
done
}
function _poll_psql() {
_setup_named_pipes
psql --no-psqlrc "${g_db_uri}" < ${g_psql_input} 2>&1 > ${g_psql_output} &
exec 3>${g_psql_input} # keep input open
_poll_loop &
g_poll_loop_pid=$!
}
function _setup_named_pipes() {
g_psql_input=$(mktemp -t --dry-run psql-psql_input.XXXX)
g_psql_output=$(mktemp -t --dry-run psql-psql_output.XXXX)
mkfifo ${g_psql_input} ${g_psql_output}
}
function _poll_loop() {
echo "LISTEN log_${g_log_name};" > ${g_psql_input}
while true; do
echo "SELECT 1;" > ${g_psql_input}
sleep 1
done
}
function cleanup() {
echo "Exiting"
kill ${g_poll_loop_pid} 2>/dev/null
echo "end; \quit" > ${g_psql_input}
rm -f ${g_psql_input}
rm -f ${g_psql_output}
exit
}
run_poll_loop
)
###### Production code #########
function print_message() {
local message=$1
echo "Received: ${message}"
}
read_messages_forever "orderdata" "postgres://samba@/postgres" "print_message"