From eda5cb29d0200ee55c0ed50d2afe1a17dbd7577a Mon Sep 17 00:00:00 2001 From: Adam Coldrick Date: Thu, 7 May 2015 17:12:56 +0000 Subject: Explain how to cancel a distbuild Cancelling a distbuild with ctrl+c no longer cancels the build itself. This commit adds some output explaining what should be done to cancel the build as well as the local process. This commit also fixes a bug where the BuildStarted event would be sent each time a chunk finished building, since it was being sent in _queue_worker_builds. This is fixed by adding a new function to be called when the build graph annotation is complete which sends BuildStarted and then calls _queue_worker_builds, which no longer sends the BuildStarted event. Change-Id: I26ddea2c9080887f449e87004411ddffe4e583b7 --- distbuild/build_controller.py | 23 ++++++++++++++++------- distbuild/initiator.py | 21 ++++++++++++--------- morphlib/buildcommand.py | 5 +++++ 3 files changed, 33 insertions(+), 16 deletions(-) diff --git a/distbuild/build_controller.py b/distbuild/build_controller.py index 3a099b82..9b934da6 100644 --- a/distbuild/build_controller.py +++ b/distbuild/build_controller.py @@ -252,7 +252,7 @@ class BuildController(distbuild.StateMachine): 'annotating', self._maybe_handle_cache_response), ('annotating', self, BuildFailed, None, None), ('annotating', self, _Annotated, 'building', - self._queue_worker_builds), + self._start_building), ('annotating', distbuild.InitiatorConnection, distbuild.CancelRequest, 'annotating', self._maybe_notify_build_cancelled), @@ -478,23 +478,32 @@ class BuildController(distbuild.StateMachine): self._components) return [a for a in artifacts if is_ready_to_build(a)] - def _queue_worker_builds(self, event_source, event): - distbuild.crash_point() - + def _build_complete(self): if not self._components: if self._artifact.state == BUILT: logging.info('Requested artifact is built') self.mainloop.queue_event(self, _Built()) - return - + return True else: if not any(c.state != BUILT for c in self._components): logging.info('Requested components are built') self.mainloop.queue_event(self, _Built()) - return + return True + return False + + def _start_building(self, event_source, event): + if self._build_complete(): + return self.mainloop.queue_event(BuildController, BuildStarted(self._request['id'])) + self._queue_worker_builds(event_source, event) + + def _queue_worker_builds(self, event_source, event): + distbuild.crash_point() + + if self._build_complete(): + return logging.debug('Queuing more worker-builds to run') if self.debug_graph_state: diff --git a/distbuild/initiator.py b/distbuild/initiator.py index 5fc74086..f1facdfe 100644 --- a/distbuild/initiator.py +++ b/distbuild/initiator.py @@ -75,6 +75,7 @@ class Initiator(distbuild.StateMachine): self._step_outputs = {} self.debug_transitions = False self.allow_detach = False + self.connection_id = None # The build-log output dir is set up in _open_output() when we # receive the first log message. Thus if we never get that far, we @@ -126,7 +127,7 @@ class Initiator(distbuild.StateMachine): logging.debug('Initiator: from controller: %s' % repr(event.msg)) handlers = { - 'build-started': lambda msg: None, + 'build-started': self._handle_build_started_message, 'build-finished': self._handle_build_finished_message, 'build-failed': self._handle_build_failed_message, 'build-cancelled': self._handle_build_cancelled_message, @@ -144,6 +145,15 @@ class Initiator(distbuild.StateMachine): handler = handlers[event.msg['type']] handler(event.msg) + def _handle_build_started_message(self, msg): + self._app.status(msg='Distbuild started with build request ' + 'ID: %(id)s. To cancel, use `morph ' + 'distbuild-cancel %(id)s`.', + id=msg['id']) + if self.allow_detach: + self.mainloop.queue_event(self._cm, distbuild.StopConnecting()) + self._jm.close() + def _handle_build_finished_message(self, msg): self.mainloop.queue_event(self, _Finished(msg)) @@ -158,6 +168,7 @@ class Initiator(distbuild.StateMachine): self._app.status(msg='Progress: %(msgtext)s', msgtext=msg['message']) def _handle_graphing_started_message(self, msg): + self.connection_id = msg['id'] self._app.status(msg='Computing build graph') def _handle_graphing_finished_message(self, msg): @@ -323,14 +334,6 @@ class InitiatorStart(Initiator): handler = handlers[msg_type] handler(event.msg) - def _handle_build_started_message(self, msg): - self._app.status(msg='Detaching distbuild from controller (build' - ' will continue on the distbuild network): ' - 'build request ID: %s' % msg['id']) - - self.mainloop.queue_event(self._cm, distbuild.StopConnecting()) - self._jm.close() - class InitiatorCancel(distbuild.StateMachine): def __init__(self, cm, conn, app, job_id): diff --git a/morphlib/buildcommand.py b/morphlib/buildcommand.py index 6a5373ab..c5d86a08 100644 --- a/morphlib/buildcommand.py +++ b/morphlib/buildcommand.py @@ -572,4 +572,9 @@ class InitiatorBuildCommand(BuildCommand): # Python exceptions. logging.info('Received KeyboardInterrupt, aborting.') for initiator in loop.state_machines_of_type(distbuild.Initiator): + connection_id = initiator.connection_id or 'ID' + self.app.status(msg='Stopping initiator process. To cancel ' + 'the build use `morph distbuild-cancel ' + '%(initiator_connection)s`.', + initiator_connection=connection_id) initiator.handle_cancel() -- cgit v1.2.1