Repository: ansible/awx
File: awx/main/management/commands/run_wsrelay.py (Python)

Code before:
            executor = MigrationExecutor(connection)
            migrating = bool(executor.migration_plan(executor.loader.graph.leaf_nodes()))
            connection.close()  # Because of async nature, main loop will use new connection, so close this
        except Exception as exc:
            time.sleep(10)  # Prevent supervisor from restarting the service too quickly and the service to enter FATAL state
            # sleeping before logging because logging rely on setting which require database connection...
            logger.warning(f'Error on startup of run_wsrelay (error: {exc}), slept for 10s...')
            return

        # In containerized deployments, migrations happen in the task container,
        # and the services running there don't start until migrations are
        # finished.
        # *This* service runs in the web container, and it's possible that it can
        # start _before_ migrations are finished, thus causing issues with the ORM
        # queries it makes (specifically, conf.settings queries).
        # This block is meant to serve as a sort of bail-out for the situation
        # where migrations aren't yet finished (similar to the migration
        # detection middleware that the uwsgi processes have) or when instance
        # registration isn't done yet
        if migrating:
            logger.info('AWX is currently migrating, retry in 10s...')
            time.sleep(10)
            return

        try:
            my_hostname = Instance.objects.my_hostname()  # This relys on settings.CLUSTER_HOST_ID which requires database connection
            logger.info('Active instance with hostname {} is registered.'.format(my_hostname))
        except RuntimeError as e:
            # the CLUSTER_HOST_ID in the task, and web instance must match and
            # ensure network connectivity between the task and web instance
            time.sleep(10)  # Prevent supervisor from restarting the service too quickly and the service to enter FATAL state
            # sleeping before logging because logging rely on setting which require database connection...
            logger.warning(f"Unable to return currently active instance: {e}, slept for 10s before return.")
            return

        if options.get('status'):
            try:
                stats_all = RelayWebsocketStatsManager.get_stats_sync()
            except redis.exceptions.ConnectionError as e:
                print(f"Unable to get Relay Websocket Status. Failed to connect to redis {e}")
                return

            data = {}
            for family in stats_all:
                if family.type == 'gauge' and len(family.samples) > 1:
                    for sample in family.samples:
                        if sample.value >= 1:
                            data[family.name] = sample.labels[family.name]
                            break
                else:
                    data[family.name] = family.samples[0].value

Review comment (suggestion):
```suggestion
            my_hostname = Instance.objects.my_hostname()  # This relies on settings.CLUSTER_HOST_ID which requires database connection
```

Code after:
            executor = MigrationExecutor(connection)
            migrating = bool(executor.migration_plan(executor.loader.graph.leaf_nodes()))
            connection.close()  # Because of async nature, main loop will use new connection, so close this
        except Exception as exc:
            time.sleep(10)  # Prevent supervisor from restarting the service too quickly and the service to enter FATAL state
            # sleeping before logging because logging rely on setting which require database connection...
            logger.warning(f'Error on startup of run_wsrelay (error: {exc}), slept for 10s...')
            return

        # In containerized deployments, migrations happen in the task container,
        # and the services running there don't start until migrations are
        # finished.
        # *This* service runs in the web container, and it's possible that it can
        # start _before_ migrations are finished, thus causing issues with the ORM
        # queries it makes (specifically, conf.settings queries).
        # This block is meant to serve as a sort of bail-out for the situation
        # where migrations aren't yet finished (similar to the migration
        # detection middleware that the uwsgi processes have) or when instance
        # registration isn't done yet
        if migrating:
            logger.info('AWX is currently migrating, retry in 10s...')
            time.sleep(10)
            return

        try:
            my_hostname = Instance.objects.my_hostname()  # This relies on settings.CLUSTER_HOST_ID which requires database connection
            logger.info('Active instance with hostname {} is registered.'.format(my_hostname))
        except RuntimeError as e:
            # the CLUSTER_HOST_ID in the task, and web instance must match and
            # ensure network connectivity between the task and web instance
            time.sleep(10)  # Prevent supervisor from restarting the service too quickly and the service to enter FATAL state
            # sleeping before logging because logging rely on setting which require database connection...
            logger.warning(f"Unable to return currently active instance: {e}, slept for 10s before return.")
            return

        if options.get('status'):
            try:
                stats_all = RelayWebsocketStatsManager.get_stats_sync()
            except redis.exceptions.ConnectionError as e:
                print(f"Unable to get Relay Websocket Status. Failed to connect to redis {e}")
                return

            data = {}
            for family in stats_all:
                if family.type == 'gauge' and len(family.samples) > 1:
                    for sample in family.samples:
                        if sample.value >= 1:
                            data[family.name] = sample.labels[family.name]
                            break
                else:
                    data[family.name] = family.samples[0].value