diff --git a/cronjobs/run-maintenance.sh b/cronjobs/run-maintenance.sh index 54799323..3651958a 100755 --- a/cronjobs/run-maintenance.sh +++ b/cronjobs/run-maintenance.sh @@ -47,16 +47,25 @@ fi ME=$( basename $0 ) # Overwrite some settings via command line arguments -while getopts "hfvp:d:" opt; do +while getopts "hfvt:p:d:" opt; do case "$opt" in h|\?) - echo "Usage: $0 [-v] [-p PHP_BINARY] [-d SUBFOLDER]"; + echo "Usage: $0 [-v] [-f] [-t TIME_IN_SEC] [-p PHP_BINARY] [-d SUBFOLDER]"; exit 0 ;; v) VERBOSE=1 ;; f) PHP_OPTS="$PHP_OPTS -f";; p) PHP_BIN=$OPTARG ;; d) SUBFOLDER=$OPTARG ;; + t) + if [[ $OPTARG =~ ^[0-9]+$ ]]; then + TIMEOUT=$OPTARG + PHP_OPTS="$PHP_OPTS -t $OPTARG" + else + echo "Option -t requires an integer" >&2 + exit 1 + fi + ;; :) echo "Option -$OPTARG requires an argument." >&2 exit 1 @@ -102,6 +111,16 @@ fi # Our PID of this shell PID=$$ +# If $PIDFILE exists and older than the time specified by -t, remove it. +if [[ -e $PIDFILE ]]; then + if [[ -n $TIMEOUT ]] && \ + [[ $(( $(date +%s) - $(stat -c %Y $PIDFILE) )) -gt $TIMEOUT ]]; then + echo "$PIDFILE exists but older than the time you specified in -t option ($TIMEOUT sec)." + echo "Removing PID file." + rm $PIDFILE + fi +fi + if [[ -e $PIDFILE ]]; then echo "Cron seems to be running already" RUNPID=$( cat $PIDFILE ) diff --git a/cronjobs/run-payout.sh b/cronjobs/run-payout.sh index 5534122f..0ec8b187 100755 --- a/cronjobs/run-payout.sh +++ b/cronjobs/run-payout.sh @@ -46,17 +46,25 @@ fi # My own name ME=$( basename $0 ) -# Overwrite some settings via command line arguments -while getopts "hfvp:d:" opt; do +while getopts "hfvt:p:d:" opt; do case "$opt" in h|\?) - echo "Usage: $0 [-v] [-p PHP_BINARY] [-d SUBFOLDER]"; + echo "Usage: $0 [-v] [-f] [-t TIME_IN_SEC] [-p PHP_BINARY] [-d SUBFOLDER]"; exit 0 ;; v) VERBOSE=1 ;; f) PHP_OPTS="$PHP_OPTS -f";; p) PHP_BIN=$OPTARG ;; d) SUBFOLDER=$OPTARG ;; + t) + if [[ $OPTARG =~ ^[0-9]+$ ]]; then + TIMEOUT=$OPTARG + PHP_OPTS="$PHP_OPTS -t $OPTARG" + else + echo "Option -t requires an integer" >&2 + exit 1 + fi + ;; :) echo "Option -$OPTARG requires an argument." >&2 exit 1 @@ -102,6 +110,16 @@ fi # Our PID of this shell PID=$$ +# If $PIDFILE exists and older than the time specified by -t, remove it. +if [[ -e $PIDFILE ]]; then + if [[ -n $TIMEOUT ]] && \ + [[ $(( $(date +%s) - $(stat -c %Y $PIDFILE) )) -gt $TIMEOUT ]]; then + echo "$PIDFILE exists but older than the time you specified in -t option ($TIMEOUT sec)." + echo "Removing PID file." + rm $PIDFILE + fi +fi + if [[ -e $PIDFILE ]]; then echo "Cron seems to be running already" RUNPID=$( cat $PIDFILE ) diff --git a/cronjobs/run-statistics.sh b/cronjobs/run-statistics.sh index 9aa29737..edcba37f 100755 --- a/cronjobs/run-statistics.sh +++ b/cronjobs/run-statistics.sh @@ -47,16 +47,25 @@ fi ME=$( basename $0 ) # Overwrite some settings via command line arguments -while getopts "hfvp:d:" opt; do +while getopts "hfvt:p:d:" opt; do case "$opt" in h|\?) - echo "Usage: $0 [-v] [-p PHP_BINARY] [-d SUBFOLDER]"; + echo "Usage: $0 [-v] [-f] [-t TIME_IN_SEC] [-p PHP_BINARY] [-d SUBFOLDER]"; exit 0 ;; v) VERBOSE=1 ;; f) PHP_OPTS="$PHP_OPTS -f";; p) PHP_BIN=$OPTARG ;; d) SUBFOLDER=$OPTARG ;; + t) + if [[ $OPTARG =~ ^[0-9]+$ ]]; then + TIMEOUT=$OPTARG + PHP_OPTS="$PHP_OPTS -t $OPTARG" + else + echo "Option -t requires an integer" >&2 + exit 1 + fi + ;; :) echo "Option -$OPTARG requires an argument." >&2 exit 1 @@ -102,6 +111,16 @@ fi # Our PID of this shell PID=$$ +# If $PIDFILE exists and older than the time specified by -t, remove it. +if [[ -e $PIDFILE ]]; then + if [[ -n $TIMEOUT ]] && \ + [[ $(( $(date +%s) - $(stat -c %Y $PIDFILE) )) -gt $TIMEOUT ]]; then + echo "$PIDFILE exists but older than the time you specified in -t option ($TIMEOUT sec)." + echo "Removing PID file." + rm $PIDFILE + fi +fi + if [[ -e $PIDFILE ]]; then echo "Cron seems to be running already" RUNPID=$( cat $PIDFILE ) diff --git a/cronjobs/shared.inc.php b/cronjobs/shared.inc.php index b16e0c3e..ce14408a 100644 --- a/cronjobs/shared.inc.php +++ b/cronjobs/shared.inc.php @@ -51,19 +51,39 @@ $cron_name = basename($_SERVER['PHP_SELF'], '.php'); require_once(BASEPATH . '../include/bootstrap.php'); require_once(BASEPATH . '../include/version.inc.php'); +// Load 3rd party logging library for running crons +$log = KLogger::instance( BASEPATH . '../logs/' . $cron_name, KLogger::INFO ); + // Command line switches array_shift($argv); -foreach ($argv as $option) { +foreach ($argv as $index => $option) { switch ($option) { case '-f': $monitoring->setStatus($cron_name . "_disabled", "yesno", 0); $monitoring->setStatus($cron_name . "_active", "yesno", 0); break; + case '-t': + // When `-t TIME_IN_SEC` is specified, we ignore the cron active flag + // if the time elapsed `TIME_IN_SEC` seconds after the last job started. + + // Check the next argument is the value for -t option. + if (!($index + 1 < count($argv)) || // check if '-t' is not the last argument. + !(ctype_digit($argv[$index + 1]))) { // check the next argument is numeric string + $log->logFatal('Option -t requires an integer.'); + $monitoring->endCronjob($cron_name, 'E0085', 3, true, false); + } + + $timeout = intval($argv[$index + 1]); + $timeElapsedFromLastStart = $dStartTime - $monitoring->getLastCronStarted($cron_name); + + if ($timeElapsedFromLastStart > $timeout) { + $log->logWarn("Previous cronjob `$cron_name` is started before than you specified by -t. Re-run forced."); + $monitoring->setStatus($cron_name . "_active", "yesno", 0); + } + break; } } -// Load 3rd party logging library for running crons -$log = KLogger::instance( BASEPATH . '../logs/' . $cron_name, KLogger::INFO ); $log->LogDebug('Starting ' . $cron_name); // Load the start time for later runtime calculations for monitoring diff --git a/include/classes/monitoring.class.php b/include/classes/monitoring.class.php index 7dd04df6..b5caae02 100644 --- a/include/classes/monitoring.class.php +++ b/include/classes/monitoring.class.php @@ -60,6 +60,16 @@ class Monitoring extends Base { return $aStatus['value']; } + /** + * Get the timestamp that last time a cronjob started + * @param name string Cronjob name + * @return int unix timestamp of last time the cronjob started + **/ + public function getLastCronStarted($name) { + $aStatus = $this->getStatus($name . '_starttime'); + return $aStatus['value']; + } + /** * Fetch a value from our table * @param name string Setting name diff --git a/include/config/error_codes.inc.php b/include/config/error_codes.inc.php index a4b33471..f01f5588 100644 --- a/include/config/error_codes.inc.php +++ b/include/config/error_codes.inc.php @@ -80,3 +80,4 @@ $aErrorCodes['E0081'] = 'Failed to insert new block into database'; $aErrorCodes['E0082'] = 'Block does not supply any usable confirmation information'; $aErrorCodes['E0083'] = 'Maintenance mode enabled, skipped'; $aErrorCodes['E0084'] = 'Error updating %s table'; +$aErrorCodes['E0085'] = 'Cron disabled due to invalid arguments';