Skip to content

Commit

Permalink
chore(sigterm): improve SIGTERM handling in loop-validate.sh to exit …
Browse files Browse the repository at this point in the history
…nicely and restart current validation (refs #59)
  • Loading branch information
mborne committed Nov 16, 2023
1 parent 855dad7 commit 4529754
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 6 deletions.
37 changes: 33 additions & 4 deletions loop-validate.sh
Original file line number Diff line number Diff line change
@@ -1,11 +1,40 @@
#!/bin/bash
set -e

SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"

while true
RUNNING=1

_term(){
echo "$BASH_SOURCE - caught signal, terminating..."
RUNNING=0
kill -s SIGTERM $child_pid
wait
}


# Note that trapping SIGWINCH is due to weird usage of this "window resized" by apache2
# (see https://bz.apache.org/bugzilla/show_bug.cgi?id=50669)
# ...propagated to STOPSIGNAL=SIGWINCH in php:8.2-apache docker image
# ...which leads to an unexpected behavior of "docker stop"
# ...and probably problems with PHP applications including console commands (Symfony, Laravel,...)
trap _term SIGTERM SIGINT SIGWINCH

echo "$BASH_SOURCE - started with PID=$$"

while [ $RUNNING -eq 1 ]
do
php "${SCRIPT_DIR}/bin/console" ign-validator:validations:process-one -vv
sleep 15
php "${SCRIPT_DIR}/bin/console" ign-validator:validations:process-one -vvv &
child_pid=$!
wait $child_pid

if [ $RUNNING -eq 0 ];
then
break;
fi

sleep 15 &
child_pid=$!
wait $child_pid
done

echo "$BASH_SOURCE - stopped"
31 changes: 29 additions & 2 deletions src/Command/Validations/ProcessOneCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,16 @@
namespace App\Command\Validations;

use App\Validation\ValidationManager;
use Psr\Log\LoggerInterface;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Command\SignalableCommandInterface;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

/**
* Helper command to process pending validations.
*/
class ProcessOneCommand extends Command
class ProcessOneCommand extends Command implements SignalableCommandInterface
{
protected static $defaultName = 'ign-validator:validations:process-one';

Expand All @@ -19,11 +21,18 @@ class ProcessOneCommand extends Command
*/
private $validationManager;

/**
* @var LoggerInterface
*/
private $logger;

public function __construct(
ValidationManager $validationManager
ValidationManager $validationManager,
LoggerInterface $logger
) {
parent::__construct();
$this->validationManager = $validationManager;
$this->logger = $logger;
}

protected function configure()
Expand All @@ -43,4 +52,22 @@ protected function execute(InputInterface $input, OutputInterface $output): int
return 0;
}

public function getSubscribedSignals(): array
{
return [\SIGINT,\SIGTERM];
}

public function handleSignal(int $signal): void
{
$this->logger->warning("[ProcessOneCommand] received stop signal while processing validation!",[
'signal' => $signal
]);
$this->validationManager->cancelProcessing();
$exitCode = 128 + $signal;
$this->logger->info("terminate process with exitCode={exitCode}",[
'exitCode' => $exitCode
]);
exit($exitCode);
}
}

27 changes: 27 additions & 0 deletions src/Validation/ValidationManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@ class ValidationManager
*/
private $zipArchiveValidator;

/**
* Current validation (in order to handle SIGTERM)
* @var Validation
*/
private $currentValidation = null;

public function __construct(
EntityManagerInterface $em,
ValidationsStorage $storage,
Expand Down Expand Up @@ -90,12 +96,33 @@ public function archive(Validation $validation)
*/
public function processOne()
{
sleep(100);
$validation = $this->getValidationRepository()->popNextPending();
if (is_null($validation)) {
$this->logger->debug("processOne : no validation pending, quitting");
return;
}
$this->currentValidation = $validation;
$this->doProcess($validation);
$this->currentValidation = null;
}

/**
* Stop currently running validation (invoked when SIGTERM is received)
*
* @return void
*/
public function cancelProcessing(){
if ( is_null($this->currentValidation) ){
$this->logger->debug("SIGTERM received, no validation in progress");
return ;
}
$this->logger->warning("Validation[{uid}]: SIGTERM received, changing state to pending",[
"uid" => $this->currentValidation->getUid()
]);
$this->currentValidation->setStatus(Validation::STATUS_PENDING);
$this->em->persist($this->currentValidation);
$this->em->flush();
}

/**
Expand Down

0 comments on commit 4529754

Please sign in to comment.