Browse Source

fix: [cron] use env as cache key to avoid improper cache hit between multiple services on same charm

master
Valentin Lab 2 weeks ago
parent
commit
704720c4cd
  1. 43
      cron/lib/common
  2. 15
      cron/test/entries_from_service

43
cron/lib/common

@ -1,11 +1,12 @@
# -*- mode: shell-script -*-
cron:get_config() {
local cfg="$1"
local cfg="$1" env_hash="$2"
local cache_file="$CACHEDIR/$FUNCNAME.cache.$(H "$@")" \
type value
local k v E E1 title command lock_opts schedule
if [ -e "$cache_file" ]; then
#debug "$FUNCNAME: SESSION cache hit $1"
debug "$FUNCNAME: SESSION cache hit $1"
cat "$cache_file"
return 0
fi
@ -13,7 +14,7 @@ cron:get_config() {
case "$type" in
"sequence")
while read-0-err E s; do
cron:get_config "$s" || return 1
cron:get_config "$s" "$env_hash" || return 1
done < <(e "$cfg" | p-err shyaml -q get-values-0 -y)
if [ "$E" != 0 ]; then
err "Failed to parse sequence while reading config."
@ -30,7 +31,7 @@ cron:get_config() {
return 1
fi
p0 "$schedule" "$lock_opts" "$k" "$command"
done < <(p-err cron:get_config "$v")
done < <(p-err cron:get_config "$v" "$env_hash")
if [ "$E1" != 0 ]; then
err "Failed to parse value of key '$k' in struct config."
return 1
@ -69,7 +70,7 @@ cron:get_config() {
err "Unrecognized type '$type'."
return 1
fi
cron:get_config "$value" || return 1
cron:get_config "$value" "$env_hash" || return 1
;;
esac > "$cache_file.tmp"
@ -89,12 +90,13 @@ cron:get_config() {
}
cron:entries_from_service() {
local service="$1" relation_cfg="$2" \
cache_file="$CACHEDIR/$FUNCNAME.cache.$(H "$@")" \
label schedule lock_opts title command full_label
label schedule lock_opts title command full_label H
if [ -e "$cache_file" ]; then
#debug "$FUNCNAME: SESSION cache hit $1"
debug "$FUNCNAME: SESSION cache hit $1"
cat "$cache_file"
return 0
fi
@ -107,6 +109,16 @@ cron:entries_from_service() {
BASE_CHARM_PATH=$(charm.get_dir "$BASE_CHARM_NAME") || return 1
export MASTER_BASE_{CHARM,SERVICE}_NAME BASE_CHARM_{PATH,NAME}
H=$(
env_vars=(MASTER_BASE_{CHARM,SERVICE}_NAME BASE_CHARM_{PATH,NAME} BASE_SERVICE_NAME)
values=()
for v in "${env_vars[@]}"; do
values+=("${!v}")
done
H "${values[@]}"
)
label="launch-$service"
while read-0-err E schedule lock_opts title command; do
lock_opts=($lock_opts)
@ -136,7 +148,8 @@ cron:entries_from_service() {
p0 "$schedule lock ${full_label} ${lock_opts[*]} -c \"$command\" 2>&1 | awk '{ print strftime(\"%Y-%m-%d %H:%M:%S %Z\"), \$0; fflush(); }' >> /var/log/cron/${full_label}_script.log"
done < <(p-err cron:get_config "$relation_cfg") > "$cache_file"
done < <(p-err cron:get_config "$relation_cfg" "$H") > "$cache_file.tmp"
mv "$cache_file.tmp" "$cache_file" >&2
if [ "$E" != 0 ]; then
rm -f "$cache_file"
err "Failed to get ${DARKYELLOW}$service${NORMAL}--${DARKBLUE}schedule-command${NORMAL}-->${DARKYELLOW}$SERVICE_NAME${NORMAL}'s config."
@ -149,7 +162,7 @@ cron:entries_from_service() {
cron:lock_opts() {
local cache_file="$CACHEDIR/$FUNCNAME.cache.$(H "$@")" \
label schedule lock_opts title command full_label
label schedule lock_opts title
if [ -e "$cache_file" ]; then
#debug "$FUNCNAME: SESSION cache hit $1"
cat "$cache_file"
@ -198,13 +211,17 @@ cron:entries() {
if [ -z "$ALL_RELATIONS" ]; then
err "Expected \$ALL_RELATIONS to be set."
exit 1
return 1
fi
export TARGET_SERVICE_NAME=$SERVICE_NAME
export TARGET_SERVICE_NAME="$SERVICE_NAME"
while read-0 service relation_cfg; do
debug "service: '$service' relation_cfg: '$relation_cfg'"
debug "service: '$service' relation_cfg:" >&2
e "$relation_cfg" | prefix " | " >&2
echo "" >&2
cron:entries_from_service "$service" "$relation_cfg" || return 1
done < <(get_service_incoming_relations "$SERVICE_NAME" "schedule-command") > "$cache_file"
done < <(get_service_incoming_relations "$SERVICE_NAME" "schedule-command") > "$cache_file.tmp"
mv "$cache_file.tmp" "$cache_file" >&2
cat "$cache_file"
}
export -f cron:entries

15
cron/test/entries_from_service

@ -154,3 +154,18 @@ noerror
is out "\
0 0 * * * lock launch-foo -p 10 -k -c \"dc run --rm foo foo\" 2>&1 | awk '{ print strftime(\"%Y-%m-%d %H:%M:%S %Z\"), \$0; fflush(); }' >> /var/log/cron/launch-foo_script.log" TRIM
try "
set -o pipefail &&
cfg='!var-expand
(0 0 * * *) {-p 10 -k} dc run --rm \$BASE_SERVICE_NAME \$MASTER_BASE_SERVICE_NAME
'
cron:entries_from_service 'foo1' \"\$cfg\" | tr '\0' '\n'
cron:entries_from_service 'foo2' \"\$cfg\" | tr '\0' '\n'
" "using relation's var, same conf, different env"
noerror
is out "\
0 0 * * * lock launch-foo1 -p 10 -k -c \"dc run --rm foo1 foo1\" 2>&1 | awk '{ print strftime(\"%Y-%m-%d %H:%M:%S %Z\"), \$0; fflush(); }' >> /var/log/cron/launch-foo1_script.log
0 0 * * * lock launch-foo2 -p 10 -k -c \"dc run --rm foo2 foo2\" 2>&1 | awk '{ print strftime(\"%Y-%m-%d %H:%M:%S %Z\"), \$0; fflush(); }' >> /var/log/cron/launch-foo2_script.log\
" TRIM
Loading…
Cancel
Save