Skip to content

Commit

Permalink
Make install wait for the db
Browse files Browse the repository at this point in the history
  • Loading branch information
sevein committed Aug 16, 2024
1 parent 99b3d2d commit cc00077
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 0 deletions.
1 change: 1 addition & 0 deletions hack/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ bootstrap: ## Bootstrap the database.
--entrypoint /src/worker/manage.py \
archivematica-worker \
install \
--wait-for-db \
--migrate \
--username="test" \
--password="test" \
Expand Down
42 changes: 42 additions & 0 deletions worker/worker/main/management/commands/install.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
import uuid
from argparse import BooleanOptionalAction
from time import sleep
from time import time

from django.contrib.auth import get_user_model
from django.core.management import call_command
from django.core.management.base import BaseCommand
from django.db import DEFAULT_DB_ALIAS
from django.db import connections
from django.db.utils import OperationalError
from tastypie.models import ApiKey

from worker.main.models import Agent
Expand All @@ -12,6 +17,12 @@

class Command(BaseCommand):
def add_arguments(self, parser):
parser.add_argument(
"--wait-for-db",
default=False,
action=BooleanOptionalAction,
help="Wait for the database.",
)
parser.add_argument(
"--migrate",
default=False,
Expand All @@ -33,6 +44,10 @@ def add_arguments(self, parser):
parser.add_argument("--site-url", required=False)

def handle(self, *args, **options):
self.print_banner("Wait for the database")
self.wait_for_db()
self.print_done()

if options["migrate"] is True:
self.print_banner("Apply migrations")
call_command("migrate", interactive=False)
Expand Down Expand Up @@ -64,6 +79,33 @@ def print_banner(self, text):
middle = f"+ {text} +"
self.stdout.write(f"\n{border}\n{middle}\n{border}\n")

def wait_for_db(self, timeout_seconds=120, stable_for_seconds=3):
connection = connections[DEFAULT_DB_ALIAS]
sleep_seconds = 1
seen_alive_at = None
started_at = time()
while True:
while True:
try:
connection.cursor().execute("SELECT 1")
if not seen_alive_at:
seen_alive_at = time()
break
except OperationalError as err:
seen_alive_at = None
elapsed_time = int(time() - started_at)
if elapsed_time >= timeout_seconds:
raise TimeoutError from err
err_message = str(err).strip()
self.stdout.write(
f"Waiting for database: {err_message}... ({elapsed_time}s)\n"
)
sleep(sleep_seconds)
uptime = int(time() - seen_alive_at)
if uptime >= stable_for_seconds:
break
sleep(sleep_seconds)


def get_setting(setting, default=""):
try:
Expand Down

0 comments on commit cc00077

Please sign in to comment.