Source code for dynamo_consistency.picker

"""
The bit of the summary table that also relies on accurate backend.
"""

import logging
import re

from . import lock
from . import config

from .summary import _connect
from .summary import NoMatchingSite

from .backend import siteinfo
from .backend import check_site


LOG = logging.getLogger(__name__)


[docs]def pick_site(pattern=None, lockname=None): """ This function also does the task of syncronizing the summary database with the inventory's list of sites that match the pattern. :param str pattern: A regex that needs to be contained in the site name :param str lockname: Name of the lock file that the site should use. Needs to be `''` for guaranteed no lock. :returns: The name of a site that is ready and hasn't run in the longest time :rtype: str :raises NoMatchingSite: If no site matches or is ready """ # First add sites that match our pattern sites = siteinfo.site_list() if pattern: sites = [site for site in sites if re.search(pattern, site)] if not sites: raise NoMatchingSite('Cannot find a site that matches %s' % pattern) conn = _connect() curs = conn.cursor() curs.executemany( 'INSERT OR IGNORE INTO sites VALUES (?, 0, 0, NULL)', [(site,) for site in sites] ) # Now get the one that hasn't run in the longest time, and is good sites = set(sites) output = None # Track not ready sites so we can update the web view not_ready = [] LOG.debug('Potential sites: %s', sites) for site, isrunning in curs.execute( """ SELECT sites.site, isrunning FROM sites LEFT JOIN stats ON sites.site=stats.site ORDER BY stats.entered ASC, sites.site ASC """): LOG.debug('Considering %s (run status %s)', site, isrunning) if site in sites and \ (isrunning == 0 or isrunning == -1) and \ (lockname is None or (lock.which(site) == lockname)): if check_site(site): output = site break else: not_ready.append(site) curs.executemany('UPDATE sites SET isrunning = -1 WHERE site = ?', [(site,) for site in not_ready]) # Lock selected site if output is not None: curs.execute('UPDATE sites SET isrunning = 1 WHERE site = ?', (output,)) conn.commit() conn.close() if output is None: raise NoMatchingSite('No sites out of %s seem to be ready' % sites) # Log the pid that will run on this site # Only logging, so don't hold the lock lock.release(lock.acquire(output)) config.SITE = output return output