Skip to content

feature request: Idle load - check-for-changes.sh improve execution interval #4414

@litetex

Description

@litetex

Context

I noticed that amongst other container docker-mailservers has an unusal high idle load on my machine.

While debugging the running process I saw that check-for-changes.sh causes roughly ~50% of the idle load

Note: ENABLE_RSPAMD is set to 1

Description

check-for-changes.sh checks every 2 seconds for changes:

_check_for_changes
sleep 2

As described above this causes a lot of idle load.

The check invokes

function _check_for_changes() {
# get chksum and check it, no need to lock config yet
_monitored_files_checksums >"${CHKSUM_FILE}.new"
cmp --silent -- "${CHKSUM_FILE}" "${CHKSUM_FILE}.new"
# cmp return codes
# 0 – files are identical
# 1 – files differ
# 2 – inaccessible or missing argument
if [[ ${?} -eq 1 ]]; then
_log 'info' 'Change detected'
_create_lock # Shared config safety lock
local CHANGED
CHANGED=$(_get_changed_files "${CHKSUM_FILE}" "${CHKSUM_FILE}.new")
_handle_changes
_remove_lock
_log 'debug' 'Completed handling of detected change'
# mark changes as applied
mv "${CHKSUM_FILE}.new" "${CHKSUM_FILE}"
fi
}

and this executes

function _monitored_files_checksums() {
# If a wildcard path pattern (or an empty ENV) would yield an invalid path
# or no results, `shopt -s nullglob` prevents it from being added.
shopt -s nullglob
declare -a STAGING_FILES CHANGED_FILES
# Supported user provided configs:
local DMS_DIR=/tmp/docker-mailserver
if [[ -d ${DMS_DIR} ]]; then
STAGING_FILES+=(
"${DMS_DIR}/postfix-accounts.cf"
"${DMS_DIR}/postfix-virtual.cf"
"${DMS_DIR}/postfix-regexp.cf"
"${DMS_DIR}/postfix-aliases.cf"
"${DMS_DIR}/postfix-relaymap.cf"
"${DMS_DIR}/postfix-sasl-password.cf"
"${DMS_DIR}/dovecot-quotas.cf"
"${DMS_DIR}/dovecot-masters.cf"
)
# Check whether Rspamd is used and if so, monitor it's changes as well
if [[ ${ENABLE_RSPAMD} -eq 1 ]] && [[ -d ${RSPAMD_DMS_D} ]]; then
readarray -d '' STAGING_FILES_RSPAMD < <(find "${RSPAMD_DMS_D}" -type f -name "*.sh" -print0)
STAGING_FILES+=("${STAGING_FILES_RSPAMD[@]}")
fi
fi
# SSL certs:
if [[ ${SSL_TYPE:-} == 'manual' ]]; then
# When using "manual" as the SSL type,
# the following variables may contain the certificate files
STAGING_FILES+=(
"${SSL_CERT_PATH:-}"
"${SSL_KEY_PATH:-}"
"${SSL_ALT_CERT_PATH:-}"
"${SSL_ALT_KEY_PATH:-}"
)
elif [[ ${SSL_TYPE:-} == 'letsencrypt' ]]; then
# React to any cert changes within the following LetsEncrypt locations:
STAGING_FILES+=(
/etc/letsencrypt/acme.json
/etc/letsencrypt/live/"${SSL_DOMAIN}"/*.pem
/etc/letsencrypt/live/"${HOSTNAME}"/*.pem
/etc/letsencrypt/live/"${DOMAINNAME}"/*.pem
)
fi
# If the file actually exists, add to CHANGED_FILES
# and generate a content hash entry:
for FILE in "${STAGING_FILES[@]}"; do
[[ -f "${FILE}" ]] && CHANGED_FILES+=("${FILE}")
done
if [[ -n ${CHANGED_FILES:-} ]]; then
sha512sum -- "${CHANGED_FILES[@]}"
fi
}

As far as I can tell these extremely frequent checks are likely only required when debugging/actively changing configuration files.

I therefore propose the following:

  1. Make the change interval configurable (e.g. using a env variable like CHECK_FOR_CHANGES_INTERVAL_SEC)
  2. Change the default interval sec to something higher like 5 or 10 to lessen the default idle load
  3. Document this somewhere
    • Recommend lower values during active development/configuration and higher ones when not

Alternatives

N/A

Applicable Users

Everyone

Are you going to implement it?

Yes, because I know the probability of someone else doing it is low and I can learn from it.

What are you going to contribute?

I can provide a PR (changed code is likey ~1 line).

See also: #2348

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    Status

    Done

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions