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 -*- # -*- mode: shell-script -*-
cron:get_config() { cron:get_config() {
local cfg="$1"
local cfg="$1" env_hash="$2"
local cache_file="$CACHEDIR/$FUNCNAME.cache.$(H "$@")" \ local cache_file="$CACHEDIR/$FUNCNAME.cache.$(H "$@")" \
type value type value
local k v E E1 title command lock_opts schedule
if [ -e "$cache_file" ]; then if [ -e "$cache_file" ]; then
#debug "$FUNCNAME: SESSION cache hit $1"
debug "$FUNCNAME: SESSION cache hit $1"
cat "$cache_file" cat "$cache_file"
return 0 return 0
fi fi
@ -13,7 +14,7 @@ cron:get_config() {
case "$type" in case "$type" in
"sequence") "sequence")
while read-0-err E s; do 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) done < <(e "$cfg" | p-err shyaml -q get-values-0 -y)
if [ "$E" != 0 ]; then if [ "$E" != 0 ]; then
err "Failed to parse sequence while reading config." err "Failed to parse sequence while reading config."
@ -30,7 +31,7 @@ cron:get_config() {
return 1 return 1
fi fi
p0 "$schedule" "$lock_opts" "$k" "$command" 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 if [ "$E1" != 0 ]; then
err "Failed to parse value of key '$k' in struct config." err "Failed to parse value of key '$k' in struct config."
return 1 return 1
@ -69,7 +70,7 @@ cron:get_config() {
err "Unrecognized type '$type'." err "Unrecognized type '$type'."
return 1 return 1
fi fi
cron:get_config "$value" || return 1
cron:get_config "$value" "$env_hash" || return 1
;; ;;
esac > "$cache_file.tmp" esac > "$cache_file.tmp"
@ -89,12 +90,13 @@ cron:get_config() {
} }
cron:entries_from_service() { cron:entries_from_service() {
local service="$1" relation_cfg="$2" \ local service="$1" relation_cfg="$2" \
cache_file="$CACHEDIR/$FUNCNAME.cache.$(H "$@")" \ 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 if [ -e "$cache_file" ]; then
#debug "$FUNCNAME: SESSION cache hit $1"
debug "$FUNCNAME: SESSION cache hit $1"
cat "$cache_file" cat "$cache_file"
return 0 return 0
fi fi
@ -107,6 +109,16 @@ cron:entries_from_service() {
BASE_CHARM_PATH=$(charm.get_dir "$BASE_CHARM_NAME") || return 1 BASE_CHARM_PATH=$(charm.get_dir "$BASE_CHARM_NAME") || return 1
export MASTER_BASE_{CHARM,SERVICE}_NAME BASE_CHARM_{PATH,NAME} 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" label="launch-$service"
while read-0-err E schedule lock_opts title command; do while read-0-err E schedule lock_opts title command; do
lock_opts=($lock_opts) 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" 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 if [ "$E" != 0 ]; then
rm -f "$cache_file" rm -f "$cache_file"
err "Failed to get ${DARKYELLOW}$service${NORMAL}--${DARKBLUE}schedule-command${NORMAL}-->${DARKYELLOW}$SERVICE_NAME${NORMAL}'s config." 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() { cron:lock_opts() {
local cache_file="$CACHEDIR/$FUNCNAME.cache.$(H "$@")" \ 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 if [ -e "$cache_file" ]; then
#debug "$FUNCNAME: SESSION cache hit $1" #debug "$FUNCNAME: SESSION cache hit $1"
cat "$cache_file" cat "$cache_file"
@ -198,13 +211,17 @@ cron:entries() {
if [ -z "$ALL_RELATIONS" ]; then if [ -z "$ALL_RELATIONS" ]; then
err "Expected \$ALL_RELATIONS to be set." err "Expected \$ALL_RELATIONS to be set."
exit 1
return 1
fi fi
export TARGET_SERVICE_NAME=$SERVICE_NAME
export TARGET_SERVICE_NAME="$SERVICE_NAME"
while read-0 service relation_cfg; do 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 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" cat "$cache_file"
} }
export -f cron:entries export -f cron:entries

15
cron/test/entries_from_service

@ -154,3 +154,18 @@ noerror
is out "\ 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 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