Files
distcloud/distributedcloud/dcorch/engine/initial_sync_manager.py
Hugo Brito 51b6e19a2c Apply black formatter to dcorch/engine
This commit applies the Black format to the `dcorch/engine`
files to ensure that it adheres to the Black code style guidelines.

Test Plan:
PASS: Success in stx-distcloud-tox-black

Story: 2011149
Task: 50445

Change-Id: Ie39ef3f89b32565c7ce9cf383d1227a0bf3f7a00
Signed-off-by: Hugo Brito <hugo.brito@windriver.com>
2024-06-28 13:45:46 +00:00

131 lines
5.0 KiB
Python

# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
# Copyright (c) 2020, 2024 Wind River Systems, Inc.
#
import eventlet
from oslo_config import cfg
from oslo_log import log as logging
from dcorch.common import consts
from dcorch.common import context
from dcorch.db import api as db_api
from dcorch.rpc import client
CONF = cfg.CONF
LOG = logging.getLogger(__name__)
# How often the initial sync thread will wake up
SYNC_INTERVAL = 10
# How long to wait after a failed sync before retrying
SYNC_FAIL_HOLD_OFF = 60
class InitialSyncManager(object):
"""Manages the initial sync for each subcloud."""
def __init__(self, *args, **kwargs):
self.context = context.get_admin_context()
self.engine_worker_rpc_client = client.EngineWorkerClient()
def init_actions(self):
"""Perform actions on initialization"""
# Since we are starting up, any initial syncs that were in progress
# should be considered failed and must be redone.
subclouds = db_api.subcloud_update_all_initial_state(
self.context,
pre_initial_sync_state=consts.INITIAL_SYNC_STATE_IN_PROGRESS,
initial_sync_state=consts.INITIAL_SYNC_STATE_REQUESTED,
)
if subclouds > 0:
LOG.info(
"Initial sync for subclouds were in progress and "
"will be re-attempted."
)
# Since we are starting up, any failed syncs won't be re-attempted
# because the timer will not be running. Reattempt them.
subclouds = db_api.subcloud_update_all_initial_state(
self.context,
pre_initial_sync_state=consts.INITIAL_SYNC_STATE_FAILED,
initial_sync_state=consts.INITIAL_SYNC_STATE_REQUESTED,
)
if subclouds > 0:
LOG.info("Initial sync for subclouds were failed and will be re-attempted.")
def initial_sync_thread(self):
"""Perform initial sync for subclouds as required."""
while True:
# Catch exceptions so the thread does not die.
try:
eventlet.greenthread.sleep(SYNC_INTERVAL)
self._initial_sync_subclouds()
except eventlet.greenlet.GreenletExit:
# We have been told to exit
return
except Exception as e:
LOG.exception(e)
def _initial_sync_subclouds(self):
"""Perform initial sync for subclouds that require it."""
subclouds = db_api.subcloud_capabilities_get_all(
self.context, initial_sync_state=consts.INITIAL_SYNC_STATE_REQUESTED
)
if not subclouds:
LOG.debug("No eligible subclouds for initial sync.")
return
LOG.info("Starting initial sync loop.")
# We want a chunksize of least 1 so add the number of workers.
chunksize = (len(subclouds) + CONF.workers) // (CONF.workers)
subcloud_capabilities = {}
for region_name, capabilities_and_ip in subclouds.items():
subcloud_capabilities[region_name] = capabilities_and_ip
if len(subcloud_capabilities) == chunksize:
# We've gathered a batch of subclouds, send it to engine worker
# to process.
try:
self.engine_worker_rpc_client.initial_sync_subclouds(
self.context, subcloud_capabilities
)
LOG.debug(
f"Sent initial sync request message for "
f"{len(subcloud_capabilities)} subclouds"
)
except Exception as e:
LOG.error(
f"Exception occurred in initial_sync for subclouds "
f"{list(subcloud_capabilities.keys())}: {e}"
)
subcloud_capabilities = {}
if subcloud_capabilities:
# We've got a partial batch...send it off for processing.
try:
self.engine_worker_rpc_client.initial_sync_subclouds(
self.context, subcloud_capabilities
)
LOG.debug(
f"Sent initial sync request message for "
f"{len(subcloud_capabilities)} subclouds"
)
except Exception as e:
LOG.error(
f"Exception occurred in initial_sync for subclouds "
f"{list(subcloud_capabilities.keys())}: {e}"
)
LOG.debug("Done sending initial sync request messages.")