989ad01358d595f619021742182be67c01dd56fd max Wed Sep 9 07:38:59 2026 -0700 UniProt otto: log an interrupted run instead of leaving a dangling START Killing a run left "START" in runLog.txt with no line after it, which reads exactly like a run that is still going. doUpdate.sh now traps INT/TERM/HUP, logs INTERRUPTED, and removes doUniprot.lock, which doUniprot's own atexit handler does not get to run on a signal and which would otherwise block the next run. Note the shell only runs the trap once the foreground doUniprot has exited, so this fires when the whole process group is killed, which is what pkill does and what actually happens in practice. refs #38300 diff --git src/hg/utils/otto/uniprot/doUpdate.sh src/hg/utils/otto/uniprot/doUpdate.sh index 24e6eb34cb9..be9ac5e6dcf 100755 --- src/hg/utils/otto/uniprot/doUpdate.sh +++ src/hg/utils/otto/uniprot/doUpdate.sh @@ -1,81 +1,87 @@ #!/bin/sh # configuration setup and cron wrapper for the doUniprot script cd /hive/data/outside/otto/uniprot || exit 1 umask 002 #echo WARNING: NOT DOWNLOADING #./doUniprot run --skipDownload runLog=runLog.txt logRun() { echo "`date '+%Y-%m-%d %H:%M:%S'` $*" >> $runLog } # activate the python environment that has the lxml XML parser. Rebuild it with # ./makeVenv.sh if this fails. if [ ! -f venv/bin/activate ] ; then logRun "PREFLIGHT-FAIL no venv" echo "UniProt update did not start: venv/bin/activate is missing." echo "Rebuild it with: cd /hive/data/outside/otto/uniprot && ./makeVenv.sh" exit 1 fi . venv/bin/activate # Do not spend 35 minutes downloading UniProt only to find out that the parser cannot # start. Run it with --help, which imports lxml and then exits, and stop here if that # fails. Invoked exactly the way doUniprot invokes it, so this tests the same python. if ! ./uniprotToTab --help > /dev/null 2>&1; then logRun "PREFLIGHT-FAIL uniprotToTab cannot start" echo "UniProt update did not start: ./uniprotToTab cannot be run." echo echo "The lxml python module does not import. Rebuild the environment with:" echo " cd /hive/data/outside/otto/uniprot && ./makeVenv.sh" echo ./uniprotToTab --help 2>&1 | tail -20 exit 1 fi +# A killed run would otherwise leave a START with no matching line, which reads the same +# as a run that is still going. Say it was interrupted, and drop the lock file, which +# doUniprot's own atexit handler does not get to run on a signal. +trap 'logRun "INTERRUPTED killed by a signal"; rm -f /hive/data/outside/uniProt/current/doUniprot.lock; exit 130' INT TERM HUP + logRun "START" ./doUniprot run > lastRun.log 2>&1 exitCode=$? +trap - INT TERM HUP logRun "END exit=$exitCode" if grep -q "Is a doUniprot process already running" lastRun.log ; then # A run from last month, or a hand-started one, is still going, or crashed and left # its lock file behind. Say so in one line instead of the failure report below: this # is not a broken pipeline, but a stale lock does need someone to look at it. logRun "LOCKED another doUniprot run holds the lock file" echo "UniProt update skipped: another doUniprot run holds the lock file." echo "If nothing is running, remove /hive/data/outside/uniProt/current/doUniprot.lock" exit 0 fi if [ $exitCode -ne 0 ] ; then # lastRun.log is overwritten by the next run, so keep a copy. Without one, a # failure that nobody reads leaves no trace on disk at all. cp -f lastRun.log lastFail.log logRun "FAIL exit=$exitCode log=lastFail.log" echo "Big UniProt update FAILED, exit code $exitCode" echo echo "Full log: /hive/data/outside/otto/uniprot/lastFail.log" echo "Restart manually with:" echo " cd /hive/data/outside/otto/uniprot && ./doUniprot run" echo "usually with the -p option to skip download and parsing of the gigantic XML." echo echo "Last 25 lines of the log:" tail -25 lastFail.log exit $exitCode fi if grep -q "are not newer than file in" lastRun.log ; then # UniProt had no new release this month. This is the normal case for most months, # so stay silent: otto crons only mail when something changed or something broke. logRun "NOCHANGE no new UniProt release on the server" exit 0 fi logRun "OK updated to `cat tab/version.txt`" echo "Big UniProt update OK" echo "Now serving: `cat tab/version.txt`"