Skip to content

Commit

Permalink
add api backend healthcheck and make python wait for it
Browse files Browse the repository at this point in the history
  • Loading branch information
bailletced committed Feb 3, 2025
1 parent 0db23f7 commit 9e7d822
Show file tree
Hide file tree
Showing 7 changed files with 110 additions and 2 deletions.
1 change: 1 addition & 0 deletions config/packages/api_platform.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ api_platform:
- "%kernel.project_dir%/src/FieldHolder/Place/Domain/Exception/"
- "%kernel.project_dir%/src/FieldHolder/Community/Domain/Exception/"
- "%kernel.project_dir%/src/Field/Domain/Exception/"
- "%kernel.project_dir%/src/System/Infrastructure/ApiPlatform/Resource/"
formats:
json: ["application/json"]
jsonld: ["application/ld+json"]
Expand Down
1 change: 0 additions & 1 deletion config/packages/security.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ security:
# Easy way to control access for large sections of your site
# Note: Only the *first* access control that matches will be used
access_control:
- { host: '%host_api%', path: ^/system/healthcheck, roles: PUBLIC_ACCESS, ips: ['127.0.0.1'] }
# - { path: ^/admin, roles: ROLE_ADMIN }
# - { path: ^/, roles: ROLE_USER }

Expand Down
6 changes: 6 additions & 0 deletions docker/python/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ RUN pip install -Ur requirements.txt

FROM python:3.9-slim as runner
WORKDIR /app/

RUN apt update && apt install -y \
curl \
jq \
&& apt clean

COPY --from=compiler /opt/venv /opt/venv

COPY usr/local/bin/docker-python-entrypoint /usr/local/bin/docker-python-entrypoint
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,13 @@
normalizationContext: ['groups' => ['communities']],
),
new Put(
security: 'is_granted("ROLE_AGENT")',
uriTemplate: '/communities/upsert',
status: 200,
processor: UpsertCommunityProcessor::class,
input: CommunityWikidataInput::class,
),
new GetCollection(
security: 'is_granted("ROLE_AGENT")',
filters: [
FieldTypeFilter::class,
FieldWikidataIdFilter::class,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

declare(strict_types=1);

namespace App\System\Infrastructure\ApiPlatform\Resource;

use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\Get;
use App\System\Infrastructure\ApiPlatform\State\Provider\SystemHealthCheckProvider;

#[ApiResource(
shortName: 'System',
operations: [
new Get(
uriTemplate: '/system/health-check',
provider: SystemHealthCheckProvider::class,
),
],
)]
final class SystemHealthCheckResource
{
public function __construct(
public bool $mysql = false,

public bool $redis = false,
) {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

declare(strict_types=1);

namespace App\System\Infrastructure\ApiPlatform\State\Provider;

use ApiPlatform\Metadata\Operation;
use ApiPlatform\State\ProviderInterface;
use App\Core\Infrastructure\Redis\RedisClient;
use App\System\Infrastructure\ApiPlatform\Resource\SystemHealthCheckResource;
use Doctrine\DBAL\Exception\ConnectionException;
use Doctrine\ORM\EntityManagerInterface;

/**
* @implements ProviderInterface<SystemHealthCheckResource>
*/
final class SystemHealthCheckProvider implements ProviderInterface
{
public function __construct(
private readonly RedisClient $redisClient,
private readonly EntityManagerInterface $em,
) {
}

public function provide(Operation $operation, array $uriVariables = [], array $context = []): SystemHealthCheckResource
{
$isMySQLUp = false;
try {
$this->em->getConnection()->fetchOne('SELECT 1');
$isMySQLUp = true;
} catch (ConnectionException) {
}

$isRedisUp = (bool) $this->redisClient->client->ping();

return new SystemHealthCheckResource(
mysql: $isMySQLUp,
redis: $isRedisUp,
);
}
}
33 changes: 33 additions & 0 deletions usr/local/bin/docker-python-entrypoint
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,39 @@ set -e
env > /etc/environment
echo -------------------; echo Versions: ; python --version ; pip --version ; echo -------------------

MAX_RETRIES=150
RETRY_INTERVAL=10

check_health() {
response=$(curl -k $OPENCHURCH_HOST/system/health-check)
if ! echo "$response" | jq -e . >/dev/null 2>&1; then
return 1
fi

mysql_status=$(echo "$response" | jq -r '.mysql')
redis_status=$(echo "$response" | jq -r '.redis')

if [ "$mysql_status" = "true" ] && [ "$redis_status" = "true" ]; then
return 0
else
return 1
fi
}

counter=0
until check_health; do
counter=$((counter + 1))
if [ $counter -eq $MAX_RETRIES ]; then
echo "api backend service unavailble after $MAX_RETRIES attemps"
exit 1
fi

echo "Attempt $counter/$MAX_RETRIES - api backend unavailable. New attempt in $RETRY_INTERVAL seconds..."
sleep $RETRY_INTERVAL
done

echo "api backend service is now available"

while true; do
/opt/venv/bin/python /app/synchro.py --entity-only diocese
/opt/venv/bin/python /app/synchro.py --entity-only parish
Expand Down

0 comments on commit 9e7d822

Please sign in to comment.