aboutsummaryrefslogtreecommitdiff
path: root/guix-build-coordinator/build-allocator.scm
diff options
context:
space:
mode:
Diffstat (limited to 'guix-build-coordinator/build-allocator.scm')
-rw-r--r--guix-build-coordinator/build-allocator.scm103
1 files changed, 77 insertions, 26 deletions
diff --git a/guix-build-coordinator/build-allocator.scm b/guix-build-coordinator/build-allocator.scm
index bba3143..02af0b4 100644
--- a/guix-build-coordinator/build-allocator.scm
+++ b/guix-build-coordinator/build-allocator.scm
@@ -36,24 +36,24 @@
args)
" "))))
- (define output-has-successful-build?
+ (define cached/list-builds-for-output
(mlambda (output)
- (log "considering missing input:" output)
- (any (lambda (output-build)
- (let ((build-successful?
- (string=? (or (assq-ref output-build 'result)
- "unknown")
- "success")))
- (when build-successful?
- (log "found successful build:" (assq-ref output-build 'uuid)))
+ (datastore-list-builds-for-output datastore output)))
- build-successful?))
- (datastore-list-builds-for-output datastore output))))
-
- (let ((agents (datastore-list-agents datastore))
- (builds (datastore-list-unprocessed-builds datastore))
- (setup-failures-hash
- (datastore-fetch-setup-failures datastore)))
+ (let* ((agents (datastore-list-agents datastore))
+ (builds (datastore-list-unprocessed-builds datastore))
+ (setup-failures-hash
+ (datastore-fetch-setup-failures datastore))
+ (derived-build-priorities-hash
+ ;; Mapping from build_id to priority, initialised at the individual
+ ;; priorities for the builds
+ (let ((table (make-hash-table (length builds))))
+ (for-each (lambda (build)
+ (hash-set! table
+ (assq-ref build 'uuid)
+ (assq-ref build 'priority)))
+ builds)
+ table)))
(define (filter-builds-for-agent agent-id)
(define (relevant-setup-failure? setup-failure)
@@ -62,14 +62,9 @@
(assq-ref setup-failure 'failure-reason)))
(cond
((string=? failure-reason "missing_inputs")
- ;; If all outputs have had at least one successful build, then the
- ;; inputs should be available. Otherwise, treat the setup failure
- ;; as still relevant (return #t)
- (not
- (every output-has-successful-build?
- (datastore-list-setup-failure-missing-inputs
- datastore
- (assq-ref setup-failure 'id)))))
+ ;; missing_inputs setup failures that should be resolved have been
+ ;; filtered out by this point, so this is a relevant setup failure
+ #t)
((string=? failure-reason "could_not_delete_outputs")
;; This problem might go away, but just don't try the same agent
;; again for now.
@@ -94,8 +89,10 @@
(define (build-sorting-function-for-agent agent-id)
(lambda (a b)
- (let ((a-priority (assq-ref a 'priority))
- (b-priority (assq-ref b 'priority)))
+ (let ((a-priority (hash-ref derived-build-priorities-hash
+ (assq-ref a 'uuid)))
+ (b-priority (hash-ref derived-build-priorities-hash
+ (assq-ref b 'uuid))))
(< b-priority a-priority))))
(define (limit-planned-builds builds)
@@ -105,6 +102,60 @@
builds)
builds))
+ ;; Go through the setup failures and look specifically at the
+ ;; missing_inputs ones. Eliminate any missing_inputs failures if all the
+ ;; missing inputs appear to have been built successfully, and update the
+ ;; derived-build-priorities-hash to reflect the priorities of builds based
+ ;; on the builds that would be "unblocked" if they were completed.
+ (for-each
+ (lambda (setup-failure-build-id)
+ (let ((setup-failures (hash-ref setup-failures-hash
+ setup-failure-build-id))
+ (setup-failure-build-derived-priority
+ (hash-ref derived-build-priorities-hash
+ setup-failure-build-id)))
+ (for-each
+ (lambda (setup-failure)
+ (when (string=? "missing_inputs"
+ (assq-ref setup-failure 'failure-reason))
+ (for-each
+ (lambda (output)
+ (let ((builds (cached/list-builds-for-output output)))
+ (if (any (lambda (output-build)
+ (string=? (or (assq-ref output-build 'result)
+ "unknown")
+ "success"))
+ builds)
+ ;; At least one build for this output has been successful,
+ ;; so delete the setup failure
+ (hash-remove! setup-failures-hash
+ setup-failure-build-id)
+ ;; The missing input isn't available, so set the derived
+ ;; priority to be as least as high as this build
+ (for-each
+ (lambda (build)
+ (when (eq? 0 (assq-ref build 'processed))
+ (let* ((missing-input-build-id
+ (assq-ref build 'uuid))
+ (missing-input-build-derived-priority
+ (hash-ref derived-build-priorities-hash
+ missing-input-build-id)))
+ (when (> setup-failure-build-derived-priority
+ missing-input-build-derived-priority)
+ ;; Bump the priority of the build
+ (hash-set!
+ derived-build-priorities-hash
+ missing-input-build-id
+ setup-failure-build-derived-priority)))))
+ builds))))
+ (datastore-list-setup-failure-missing-inputs
+ datastore
+ (assq-ref setup-failure 'id)))))
+ setup-failures)))
+ (hash-map->list
+ (lambda (key value) key)
+ setup-failures-hash))
+
(let ((result
(append-map
(lambda (agent-id)