summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--distbuild/build_controller.py33
1 files changed, 25 insertions, 8 deletions
diff --git a/distbuild/build_controller.py b/distbuild/build_controller.py
index d731c497..f7786c8f 100644
--- a/distbuild/build_controller.py
+++ b/distbuild/build_controller.py
@@ -192,7 +192,14 @@ class BuildController(distbuild.StateMachine):
('annotating', distbuild.InitiatorConnection,
distbuild.InitiatorDisconnect, None,
self._maybe_abort),
-
+
+ # The exact WorkerConnection that is doing our building changes
+ # from build to build. We must listen to all messages from all
+ # workers, and choose whether to change state inside the callback.
+ # (An alternative would be to manage a set of temporary transitions
+ # specific to WorkerConnection instances that our currently
+ # building for us, but the state machines are not intended to
+ # behave that way).
('building', distbuild.WorkerConnection,
distbuild.WorkerBuildStepStarted, 'building',
self._relay_build_step_started),
@@ -205,9 +212,10 @@ class BuildController(distbuild.StateMachine):
('building', distbuild.WorkerConnection,
distbuild.WorkerBuildFinished, 'building',
self._check_result_and_queue_more_builds),
- ('building', distbuild.WorkerConnection,
- distbuild.WorkerBuildFailed, None,
- self._notify_build_failed),
+ ('building', distbuild.WorkerConnection,
+ distbuild.WorkerBuildFailed, 'building',
+ self._maybe_notify_build_failed),
+ ('building', self, _Abort, None, None),
('building', self, _Built, None, self._notify_build_done),
('building', distbuild.InitiatorConnection,
distbuild.InitiatorDisconnect, 'building',
@@ -514,15 +522,22 @@ class BuildController(distbuild.StateMachine):
self._queue_worker_builds(None, event)
- def _notify_build_failed(self, event_source, event):
+ def _maybe_notify_build_failed(self, event_source, event):
distbuild.crash_point()
+
if event.msg['id'] != self._request['id']:
- return # not for us
+ return
artifact = self._find_artifact(event.artifact_cache_key)
+
if artifact is None:
- # This is not the event you are looking for.
- return
+ logging.error(
+ 'BuildController %r: artifact %s is not in our build graph!',
+ self, artifact)
+ # We abort the build in this case on the grounds that something is
+ # very wrong internally, and it's best for the initiator to receive
+ # an error than to be left hanging.
+ self.mainloop.queue_event(self, _Abort())
logging.info(
'Build step failed for %s: %s', artifact.name, repr(event.msg))
@@ -549,6 +564,8 @@ class BuildController(distbuild.StateMachine):
cancel = BuildCancel(self._request['id'])
self.mainloop.queue_event(BuildController, cancel)
+ self.mainloop.queue_event(self, _Abort())
+
def _notify_build_done(self, event_source, event):
distbuild.crash_point()