offload: Distinguish between 'decline' and 'postpone'.

* guix/scripts/offload.scm (transfer-and-offload): New procedure, with
  core formerly in 'process-request'.
  (choose-build-machine): Remove 'requirements' parameter.
  (process-request): Reply 'decline' when none of MACHINES matches the
  requirements, and 'postpone' when MACHINES are busy.
This commit is contained in:
Ludovic Courtès 2014-03-09 14:05:30 +01:00
parent 0e6260a493
commit 88da0b6888
1 changed files with 67 additions and 42 deletions

View File

@ -199,6 +199,43 @@ there, and write the build log to LOG-PORT. Return the exit status."
(close-pipe pipe))) (close-pipe pipe)))
(define* (transfer-and-offload drv machine
#:key
(inputs '())
(outputs '())
(max-silent-time 3600)
(build-timeout 7200)
print-build-trace?)
"Offload DRV to MACHINE. Prior to the actual offloading, transfer all of
INPUTS to MACHINE; if building DRV succeeds, retrieve all of OUTPUTS from
MACHINE."
;; Acquire MACHINE's exclusive lock to serialize file transfers
;; to/from MACHINE in the presence of several 'offload' hook
;; instance.
(when (with-machine-lock machine 'bandwidth
(send-files (cons (derivation-file-name drv) inputs)
machine))
(let ((status (offload drv machine
#:print-build-trace? print-build-trace?
#:max-silent-time max-silent-time
#:build-timeout build-timeout)))
(if (zero? status)
(begin
;; Likewise (see above.)
(with-machine-lock machine 'bandwidth
(retrieve-files outputs machine))
(format (current-error-port)
"done with offloaded '~a'~%"
(derivation-file-name drv)))
(begin
(format (current-error-port)
"derivation '~a' offloaded to '~a' failed \
with exit code ~a~%"
(derivation-file-name drv)
(build-machine-name machine)
(status:exit-val status))
(primitive-exit (status:exit-val status)))))))
(define (send-files files machine) (define (send-files files machine)
"Send the subset of FILES that's missing to MACHINE's store. Return #t on "Send the subset of FILES that's missing to MACHINE's store. Return #t on
success, #f otherwise." success, #f otherwise."
@ -387,8 +424,8 @@ connections allowed to MACHINE."
;; List of acquired build slots (open ports). ;; List of acquired build slots (open ports).
'()) '())
(define (choose-build-machine requirements machines) (define (choose-build-machine machines)
"Return the best machine among MACHINES fulfilling REQUIREMENTS, or #f." "Return the best machine among MACHINES, or #f."
;; Proceed like this: ;; Proceed like this:
;; 1. Acquire the global machine-choice lock. ;; 1. Acquire the global machine-choice lock.
@ -411,9 +448,7 @@ connections allowed to MACHINE."
(and (pred machine) (and (pred machine)
(list machine slot))))) (list machine slot)))))
(let ((machines+slots (sort (filter (undecorate (let ((machines+slots (sort machines+slots
(cut machine-matches? <> requirements))
machines+slots)
(undecorate machine-less-loaded-or-faster?)))) (undecorate machine-less-loaded-or-faster?))))
(match machines+slots (match machines+slots
(((best slot) (others slots) ...) (((best slot) (others slots) ...)
@ -440,39 +475,29 @@ connections allowed to MACHINE."
(reqs (build-requirements (reqs (build-requirements
(system system) (system system)
(features features))) (features features)))
(machine (choose-build-machine reqs (build-machines)))) (candidates (filter (cut machine-matches? <> reqs)
(build-machines))))
(match candidates
(()
;; We'll never be able to match REQS.
(display "# decline\n"))
((_ ...)
(let ((machine (choose-build-machine candidates)))
(if machine (if machine
(begin (begin
;; Offload DRV to MACHINE.
(display "# accept\n") (display "# accept\n")
(let ((inputs (string-tokenize (read-line))) (let ((inputs (string-tokenize (read-line)))
(outputs (string-tokenize (read-line)))) (outputs (string-tokenize (read-line))))
;; Acquire MACHINE's exclusive lock to serialize file transfers (transfer-and-offload drv machine
;; to/from MACHINE in the presence of several 'offload' hook #:inputs inputs
;; instance. #:outputs outputs
(when (with-machine-lock machine 'bandwidth
(send-files (cons (derivation-file-name drv) inputs)
machine))
(let ((status (offload drv machine
#:print-build-trace? print-build-trace?
#:max-silent-time max-silent-time #:max-silent-time max-silent-time
#:build-timeout build-timeout))) #:build-timeout build-timeout
(if (zero? status) #:print-build-trace? print-build-trace?)))
(begin
;; Likewise (see above.) ;; Not now, all the machines are busy.
(with-machine-lock machine 'bandwidth (display "# postpone\n")))))))
(retrieve-files outputs machine))
(format (current-error-port)
"done with offloaded '~a'~%"
(derivation-file-name drv)))
(begin
(format (current-error-port)
"derivation '~a' offloaded to '~a' failed \
with exit code ~a~%"
(derivation-file-name drv)
(build-machine-name machine)
(status:exit-val status))
(primitive-exit (status:exit-val status))))))))
(display "# decline\n"))))
(define-syntax-rule (with-nar-error-handling body ...) (define-syntax-rule (with-nar-error-handling body ...)
"Execute BODY with any &nar-error suitably reported to the user." "Execute BODY with any &nar-error suitably reported to the user."