99 lines
4.1 KiB
Python
99 lines
4.1 KiB
Python
# Copyright 2016 Hewlett-Packard Development Company, L.P.
|
|
#
|
|
# 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.
|
|
#
|
|
|
|
import time
|
|
|
|
from oslo_config import cfg
|
|
from oslo_log import log as logging
|
|
|
|
from octavia.common import exceptions
|
|
from octavia.db import api as db_apis
|
|
from octavia.db import repositories as repo
|
|
|
|
LOG = logging.getLogger(__name__)
|
|
|
|
CONF = cfg.CONF
|
|
CONF.import_group('haproxy_amphora', 'octavia.common.config')
|
|
|
|
|
|
class AmphoraBuildRateLimit(object):
|
|
|
|
def __init__(self):
|
|
self.amp_build_slots_repo = repo.AmphoraBuildSlotsRepository()
|
|
self.amp_build_req_repo = repo.AmphoraBuildReqRepository()
|
|
|
|
def add_to_build_request_queue(self, amphora_id, build_priority):
|
|
self.amp_build_req_repo.add_to_build_queue(
|
|
db_apis.get_session(),
|
|
amphora_id=amphora_id,
|
|
priority=build_priority)
|
|
LOG.debug("Added build request for amphora %s to the queue",
|
|
amphora_id)
|
|
self.wait_for_build_slot(amphora_id)
|
|
LOG.info("Build slot for amphora %s is ready", amphora_id)
|
|
|
|
def has_build_slot(self):
|
|
build_rate_limit = CONF.haproxy_amphora.build_rate_limit
|
|
session = db_apis.get_session()
|
|
with session.begin(subtransactions=True):
|
|
used_build_slots = (self.amp_build_slots_repo
|
|
.get_used_build_slots_count(session))
|
|
available_build_slots = build_rate_limit - used_build_slots
|
|
LOG.debug("Available build slots %d", available_build_slots)
|
|
return available_build_slots > 0
|
|
|
|
def has_highest_priority(self, amphora_id):
|
|
session = db_apis.get_session()
|
|
with session.begin(subtransactions=True):
|
|
highest_priority_build_req = (
|
|
self.amp_build_req_repo.get_highest_priority_build_req(
|
|
session))
|
|
LOG.debug("Highest priority req: %s, Current req: %s",
|
|
highest_priority_build_req, amphora_id)
|
|
return amphora_id == highest_priority_build_req
|
|
|
|
def update_build_status_and_available_build_slots(self, amphora_id):
|
|
session = db_apis.get_session()
|
|
with session.begin(subtransactions=True):
|
|
self.amp_build_slots_repo.update_count(session, action='increment')
|
|
self.amp_build_req_repo.update_req_status(session, amphora_id)
|
|
|
|
def remove_from_build_req_queue(self, amphora_id):
|
|
session = db_apis.get_session()
|
|
with session.begin(subtransactions=True):
|
|
self.amp_build_req_repo.delete(session, amphora_id=amphora_id)
|
|
self.amp_build_slots_repo.update_count(session, action='decrement')
|
|
LOG.debug("Removed request for %s from queue"
|
|
" and released the build slot", amphora_id)
|
|
|
|
def remove_all_from_build_req_queue(self):
|
|
session = db_apis.get_session()
|
|
with session.begin(subtransactions=True):
|
|
self.amp_build_req_repo.delete_all(session)
|
|
self.amp_build_slots_repo.update_count(session, action='reset')
|
|
LOG.debug("Removed all the build requests and "
|
|
"released the build slots")
|
|
|
|
def wait_for_build_slot(self, amphora_id):
|
|
LOG.debug("Waiting for a build slot")
|
|
for i in range(CONF.haproxy_amphora.build_active_retries):
|
|
if (self.has_build_slot() and
|
|
self.has_highest_priority(amphora_id)):
|
|
self.update_build_status_and_available_build_slots(amphora_id)
|
|
return
|
|
time.sleep(CONF.haproxy_amphora.build_retry_interval)
|
|
self.remove_all_from_build_req_queue()
|
|
raise exceptions.ComputeBuildQueueTimeoutException()
|