-
Notifications
You must be signed in to change notification settings - Fork 2
/
worker.sh
executable file
·170 lines (154 loc) · 3.92 KB
/
worker.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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
#!/bin/bash
# Handle SIGTERM and SIGINT signals
trap worker_graceful_stop SIGTERM SIGINT
# Include config file
[ -r "$HOME/.yastq.conf" ] && source "$HOME/.yastq.conf" || {
[ -r "/etc/yastq.conf" ] && source "/etc/yastq.conf" || { echo "Error: loading config file failed" 1>&2; exit 1; }
}
# Include common file
[ -r "$COMMON_SCRIPT_FILE" ] && source "$COMMON_SCRIPT_FILE" || { echo "Error: loading common file failed" 1>&2; exit 1; }
##
## Prevent next iterations
##
worker_graceful_stop()
{
log_info "worker" "Finishing (signal handled)"
PREVENT_ITERATIONS=1
}
##
## Execute command in new terminal and return its exit code
##
## Params:
## $1 - command
##
## Returns:
## command exit code
##
worker_eval()
{
local COMMAND=$1
log_trace "worker" "Executing command [$COMMAND] ..."
bash -c "$COMMAND" &
wait $!
EXIT_CODE=$?
if [ 0 = "$EXIT_CODE" ]
then
log_trace "worker" "Executing command [$COMMAND] ok'"
return 0
else
log_trace "worker" "Executing command [$COMMAND] failed (Exit code [$EXIT_CODE])'"
return $EXIT_CODE
fi
}
##
## Reads task from tasks pipe
##
## Returns:
## 0 - on success
## 1 - on locking failure
## 2 - on read failure
##
## Exports:
## RESULT
##
worker_task_read()
{
local TASK_DATA
unset -v RESULT
log_debug "worker" "Reading task from tasks pipe [$TASKS_PIPE] ..."
{
# asyncronous execute flock and wait its exit
# it needed because flock does not stops when script handling signal
if flock -x 200 & wait $!
then
if read -a TASK_DATA 0<"$TASKS_PIPE"
then
log_debug "worker" "Reading task from tasks pipe [$TASKS_PIPE] ok"
RESULT=("${TASK_DATA[@]}")
return 0
else
log_debug "worker" "Reading task from tasks pipe [$TASKS_PIPE] failed (Reading failed with code [$?])"
return 2
fi
else
log_debug "worker" "Reading task from tasks pipe [$TASKS_PIPE] failed (Locking failed with code [$?])"
return 1
fi
} 200<>"$TASKS_PIPE_LOCK"
}
##
## Executes specified task with handlers
##
## Params:
## $1 - TASK id
## $2 - TASK command
## $3 - SUCC handler command
## $4 - FAIL handler command
## $5 - TASK options
##
## Returns:
## 0 - on success
##
worker_task_execute()
{
local TASK_ID=$1
local TASK_GOAL=$2
local TASK_SUCC=$3
local TASK_FAIL=$4
local TASK_OPTIONS=$5
if [[ "$TASK_OPTIONS" == *APPEND_ID_TASK* ]]
then
TASK_GOAL="$TASK_GOAL $TASK_ID"
fi
if [[ "$TASK_OPTIONS" == *APPEND_ID_SUCC* ]]
then
TASK_SUCC="$TASK_SUCC $TASK_ID"
fi
if [[ "$TASK_OPTIONS" == *APPEND_ID_FAIL* ]]
then
TASK_FAIL="$TASK_FAIL $TASK_ID"
fi
log_debug "worker" "Executing task goal [$TASK_GOAL] ..."
if worker_eval "$TASK_GOAL"
then
log_debug "worker" "Executing task goal [$TASK_GOAL] ok"
log_debug "worker" "Executing task success handler [$TASK_SUCC] ..."
if worker_eval "$TASK_SUCC"
then
log_debug "worker" "Executing task success handler [$TASK_SUCC] ok"
else
log_debug "worker" "Executing task success handler [$TASK_SUCC] failed (Exit code [$?])"
fi
else
log_debug "worker" "Executing task goal [$TASK_GOAL] failed (Exit code [$?])"
log_debug "worker" "Executing task failure handler [$TASK_FAIL] ..."
if worker_eval "$TASK_FAIL"
then
log_debug "worker" "Executing task failure handler [$TASK_FAIL] ok"
else
log_debug "worker" "Executing task failure handler [$TASK_FAIL] failed (Exit code [$?])"
fi
fi
return 0
}
log_info "worker" "Starting"
while [ -z "$PREVENT_ITERATIONS" ]
do
log_info "worker" "Reading task ..."
if worker_task_read && [ -n "$RESULT" ]
then
log_info "worker" "Reading task ok"
TASK_INFO=("${RESULT[@]}")
log_info "worker" "Executing task [${TASK_INFO[0]}] ..."
if worker_task_execute "${TASK_INFO[@]:0:5}"
then
log_info "worker" "Executing task [${TASK_INFO[0]}] ok"
else
log_info "worker" "Executing task [${TASK_INFO[0]}] failed (Task execute failed with code [$?])"
fi
else
log_info "worker" "Reading task failed (Task read failed with code [$?])"
sleep 1s
fi
done
log_info "worker" "Exiting"