Commit e4fb8842 authored by Raoul Hidalgo Charman's avatar Raoul Hidalgo Charman
Browse files

Smarter bot calls

Bots now have a timeout option, which the server looks at to determine how
long they wait on a job becoming available. As soon as a job becomes available
server responds with a lease. If it gets to the timeout then the server will
tell the bot there is no work and it will then update again and wait.
parent 589ffa40
Loading
Loading
Loading
Loading
+6 −6
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ from buildgrid.bot.bot_session import BotSession, Device, Worker

from ..bots import buildbox, dummy, host
from ..cli import pass_context
from ...settings import INTERVAL_BUFFER


@click.group(name='bot', short_help="Create and register bot clients.")
@@ -52,7 +53,7 @@ from ..cli import pass_context
              help="Public CAS client certificate for TLS (PEM-encoded)")
@click.option('--cas-server-cert', type=click.Path(exists=True, dir_okay=False), default=None,
              help="Public CAS server certificate for TLS (PEM-encoded)")
@click.option('--update-period', type=click.FLOAT, default=0.5, show_default=True,
@click.option('--update-period', type=click.FLOAT, default=30, show_default=True,
              help="Time period for bot updates to the server in seconds.")
@click.option('--parent', type=click.STRING, default='main', show_default=True,
              help="Targeted farm resource.")
@@ -64,7 +65,6 @@ def cli(context, parent, update_period, remote, client_key, client_cert, server_

    context.remote = '{}:{}'.format(url.hostname, url.port or 50051)
    context.remote_url = remote
    context.update_period = update_period
    context.parent = parent

    if url.scheme == 'http':
@@ -123,7 +123,7 @@ def cli(context, parent, update_period, remote, client_key, client_cert, server_
    context.logger = logging.getLogger(__name__)
    context.logger.debug("Starting for remote {}".format(context.remote))

    interface = bot_interface.BotInterface(context.channel)
    interface = bot_interface.BotInterface(context.channel, update_period)

    worker = Worker()
    worker.add_device(Device())
@@ -141,7 +141,7 @@ def run_dummy(context):
    Creates a session, accepts leases, does fake work and updates the server.
    """
    try:
        b = bot.Bot(context.bot_session, context.update_period)
        b = bot.Bot(context.bot_session)
        b.session(dummy.work_dummy,
                  context)
    except KeyboardInterrupt:
@@ -156,7 +156,7 @@ def run_host_tools(context):
    result back to CAS.
    """
    try:
        b = bot.Bot(context.bot_session, context.update_period)
        b = bot.Bot(context.bot_session)
        b.session(host.work_host_tools,
                  context)
    except KeyboardInterrupt:
@@ -177,7 +177,7 @@ def run_buildbox(context, local_cas, fuse_dir):
    context.fuse_dir = fuse_dir

    try:
        b = bot.Bot(context.bot_session, context.update_period)
        b = bot.Bot(context.bot_session)
        b.session(buildbox.work_buildbox,
                  context)
    except KeyboardInterrupt:
+1 −3
Original line number Diff line number Diff line
@@ -29,11 +29,10 @@ class Bot:
    Creates a local BotSession.
    """

    def __init__(self, bot_session, update_period=1):
    def __init__(self, bot_session):
        self.logger = logging.getLogger(__name__)

        self._bot_session = bot_session
        self._update_period = update_period

    def session(self, work, context):
        loop = asyncio.get_event_loop()
@@ -55,4 +54,3 @@ class Bot:
        """
        while True:
            self._bot_session.update_bot_session()
            await asyncio.sleep(self._update_period)
+3 −2
Original line number Diff line number Diff line
@@ -30,10 +30,11 @@ class BotInterface:
    Interface handles calls to the server.
    """

    def __init__(self, channel):
    def __init__(self, channel, interval):
        self.logger = logging.getLogger(__name__)
        self.logger.info(channel)
        self._stub = bots_pb2_grpc.BotsStub(channel)
        self._interval = interval

    def create_bot_session(self, parent, bot_session):
        request = bots_pb2.CreateBotSessionRequest(parent=parent,
@@ -44,4 +45,4 @@ class BotInterface:
        request = bots_pb2.UpdateBotSessionRequest(name=bot_session.name,
                                                   bot_session=bot_session,
                                                   update_mask=update_mask)
        return self._stub.UpdateBotSession(request)
        return self._stub.UpdateBotSession(request, timeout=self._interval)
+5 −2
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import uuid
from buildgrid._exceptions import InvalidArgumentError, OutOfSyncError

from ..job import LeaseState
from ...settings import INTERVAL_BUFFER


class BotsInterface:
@@ -73,7 +74,7 @@ class BotsInterface:

        return bot_session

    def update_bot_session(self, name, bot_session):
    def update_bot_session(self, name, bot_session, deadline=None):
        """ Client updates the server. Any changes in state to the Lease should be
        registered server side. Assigns available leases with work.
        """
@@ -87,7 +88,9 @@ class BotsInterface:

        # TODO: Send worker capabilities to the scheduler!
        if not bot_session.leases:
            leases = self._scheduler.request_job_leases({})
            leases = self._scheduler.request_job_leases(
                {}, block=True if deadline else None,
                timeout=deadline - INTERVAL_BUFFER if deadline else None)
            if leases:
                bot_session.leases.extend(leases)

+3 −1
Original line number Diff line number Diff line
@@ -64,8 +64,10 @@ class BotsService(bots_pb2_grpc.BotsServicer):
            instance_name = ''.join(names[0:-1])

            instance = self._get_instance(instance_name)
            # server side context time_remaining is maxint - unix time
            return instance.update_bot_session(request.name,
                                               request.bot_session)
                                               request.bot_session,
                                               context.time_remaining())

        except InvalidArgumentError as e:
            self.logger.error(e)
Loading